From e6a62220880943c46215a7f7d307e83e7231e568 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Tue, 17 Jan 2023 21:59:14 -0800 Subject: [PATCH] Sanitize eventdata. --- lib/prisma.js | 15 ++++++++++++--- pages/api/websites/[id]/index.js | 16 ++++++++++++---- queries/analytics/event/getEventData.js | 16 +++++++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/prisma.js b/lib/prisma.js index b6cb7d5b..9f995b00 100644 --- a/lib/prisma.js +++ b/lib/prisma.js @@ -97,6 +97,16 @@ function getTimestampInterval(field) { } } +function getSanitizedColumns(columns) { + return Object.keys(columns).reduce((acc, keyName) => { + const sanitizedProperty = keyName.replace(/[^\w\s_]/g, ''); + + acc[sanitizedProperty] = columns[keyName]; + + return acc; + }, {}); +} + function getJsonField(column, property, isNumber, params) { const db = getDatabaseType(process.env.DATABASE_URL); @@ -113,9 +123,7 @@ function getJsonField(column, property, isNumber, params) { } if (db === MYSQL) { - params.push(`$.?${params.length}`); - - return `${column} ->> ${params.length}`; + return `${column} ->> '$.${property}'`; } } @@ -276,6 +284,7 @@ export default { getFilterQuery, getEventDataColumnsQuery, getEventDataFilterQuery, + getSanitizedColumns, parseFilters, rawQuery, transaction, diff --git a/pages/api/websites/[id]/index.js b/pages/api/websites/[id]/index.js index 57b053b6..74f11c95 100644 --- a/pages/api/websites/[id]/index.js +++ b/pages/api/websites/[id]/index.js @@ -10,17 +10,21 @@ export default async (req, res) => { const { id: websiteUuid } = req.query; - if (!(await allowQuery(req, TYPE_WEBSITE, false))) { - return unauthorized(res); - } - if (req.method === 'GET') { + if (!(await allowQuery(req, TYPE_WEBSITE))) { + return unauthorized(res); + } + const website = await getWebsite({ websiteUuid }); return ok(res, website); } if (req.method === 'POST') { + if (!(await allowQuery(req, TYPE_WEBSITE, false))) { + return unauthorized(res); + } + const { name, domain, owner, enableShareUrl, shareId } = req.body; const { accountUuid } = req.auth; @@ -58,6 +62,10 @@ export default async (req, res) => { } if (req.method === 'DELETE') { + if (!(await allowQuery(req, TYPE_WEBSITE, false))) { + return unauthorized(res); + } + await deleteWebsite(websiteUuid); return ok(res); diff --git a/queries/analytics/event/getEventData.js b/queries/analytics/event/getEventData.js index 281c9f22..08d7bc03 100644 --- a/queries/analytics/event/getEventData.js +++ b/queries/analytics/event/getEventData.js @@ -10,15 +10,21 @@ export async function getEventData(...args) { } async function relationalQuery(websiteId, { startDate, endDate, event_name, columns, filters }) { - const { rawQuery, getEventDataColumnsQuery, getEventDataFilterQuery, toUuid } = prisma; + const { + rawQuery, + getEventDataColumnsQuery, + getEventDataFilterQuery, + toUuid, + getSanitizedColumns, + } = prisma; + const sanitizedColumns = getSanitizedColumns(columns); const params = [websiteId, startDate, endDate]; if (event_name) { params.push(event_name); } - const columnQuery = getEventDataColumnsQuery('event_data.event_data', columns, params); - + const columnQuery = getEventDataColumnsQuery('event_data.event_data', sanitizedColumns, params); const filterQuery = Object.keys(filters).length > 0 ? `and ${getEventDataFilterQuery('event_data.event_data', filters, params)}` @@ -38,10 +44,10 @@ async function relationalQuery(websiteId, { startDate, endDate, event_name, colu ${filterQuery}`, params, ).then(results => { - const fields = Object.keys(columns); + const fields = Object.keys(sanitizedColumns); return Object.keys(results[0]).map((a, i) => { - return { x: `${columns[fields[i]]}(${fields[i]})`, y: results[0][i] }; + return { x: `${sanitizedColumns[fields[i]]}(${fields[i]})`, y: results[0][i] }; }); }); }