From 0af416d8be418a6419d38328233836185e7f3914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Wed, 30 Mar 2022 13:16:55 +0200 Subject: [PATCH] feat: make rawStatements user-configurable In some cases knex might be used through a helper function that uses different name than any of predefined ones (raw, joinRaw, whereRaw). In this case allowing users to add different function names can be useful. For example ``` db.wrapQuery = (query) => (...args) => knex.query(query, args) const getUserById = db.wrapQuery('select * from ' + table + ' where id = ?') ``` --- README.md | 1 + rules/avoid-injections.js | 21 +++++++++++++++++---- rules/avoid-injections.test.js | 12 ++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8b3ac30..3bb4dcf 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ include the library itself (`knex`), but also transaction variables (`trx`, { "settings": { "knex": { + "rawStatements": "^(raw|whereRaw|joinRaw)$", "builderName": "^(knex|transaction)$" } } diff --git a/rules/avoid-injections.js b/rules/avoid-injections.js index 59d2d23..7200503 100644 --- a/rules/avoid-injections.js +++ b/rules/avoid-injections.js @@ -10,16 +10,29 @@ module.exports = { }, create(context) { - const rawStatements = /^(raw|whereRaw|joinRaw)$/; + const options = { + rawStatements: /^(raw|whereRaw|joinRaw)$/, + builderNamePattern: null, + }; + + if (context.settings && context.settings.knex) { + const { + rawStatements, + builderName: builderNamePattern, + } = context.settings.knex; + + if (rawStatements) options.rawStatements = rawStatements; + if (builderNamePattern) options.builderNamePattern = builderNamePattern; + } return { - [`CallExpression[callee.property.name=${rawStatements}][arguments.0.type!='Literal']`]( + [`CallExpression[callee.property.name=${options.rawStatements}][arguments.0.type!='Literal']`]( node, ) { - if (context.settings && context.settings.knex) { + const { builderNamePattern } = options; + if (builderNamePattern) { const builder = node.callee.object; const builderName = builder.name || builder.callee.name; - const { builderName: builderNamePattern } = context.settings.knex; if ( builderNamePattern instanceof RegExp && diff --git a/rules/avoid-injections.test.js b/rules/avoid-injections.test.js index 9c56148..141f84e 100644 --- a/rules/avoid-injections.test.js +++ b/rules/avoid-injections.test.js @@ -84,5 +84,17 @@ tester.run("avoid-injections", rule, { }, }, ), + + invalidCase( + 'db.wrapQuery("select * from " + table, null);', + [{ messageId: "avoid", data: { query: "wrapQuery" } }], + { + settings: { + knex: { + rawStatements: /^(raw|whereRaw|joinRaw|wrapQuery)$/, + }, + }, + }, + ), ], });