我对node还不太熟悉,使用sqlstring进行动态参数化查询时遇到了问题。
下面代码的问题是,过滤器是可选的,这取决于用户传递到函数中的内容,因此它们的顺序可以更改(这使得很难分别传递每个过滤器参数)。据我所知,Sqlstring使用顺序来确定哪个参数匹配正确的问号。
所以我只需要一次将所有过滤器传递给sql string,但是如果没有过滤器处于活动状态,那么我只需要为filters变量留下一个空字符串,这将抛出一个sql语法错误。

let filter = idList !== '' ? ` AND id IN(${idList})` : '';
filter += locationsList !== '' ? ` AND a.locationID IN(${locationsList})` : '';
filter += start !== undefined ? ` AND a.lastEdited >= ${start}` : '';
filter += end !== undefined ? ` AND a.lastEdited <= ${end}` : '';
filter += name !== undefined ? ` AND a.name LIKE '%${name}%'` : '';

const qry = `
SELECT
a.id 'id'
,a.number 'number'
,a.name 'name'
,a.locationID 'locationID'
,a.location 'location'
,a.lastEdited 'lastEdited'
,a.userID 'owner'
FROM tbl_foo_${'?'} a
WHERE a.id > ${'?'} ${'?'} LIMIT ${'?'};`;

let values = [ id, cursor, filter, limit ];

const rows = query(db, qry, values);

//inside of the query function it does this and then runs the query against the database
if (qry.includes('?')) {
sanitizedQry = sqlstring.format(qry, values);
}

它生成的查询如下所示:
SELECT
a.id 'id'
,a.number 'number'
,a.name 'name'
,a.locationID 'locationID'
,a.location 'location'
,a.lastEdited 'lastEdited'
,a.userID 'owner'
FROM tbl_foo_36 a
WHERE a.id > 1 '' LIMIT 100;

有更好的办法吗?

最佳答案

如果你看一下sqlstring npm page,上面写着关于SqlString.format
这看起来类似于MySQL中准备好的语句,但实际上它只是在内部使用相同的SqlString.escape()方法。
适当地使用SqlString.escape会更好。
但问题是,您没有在需要的地方防止SQL注入。例如,在这个语句中,您应该有注入保护,而您没有。下面是它应该是什么样子的示例:

filter += name !== undefined ? ` AND a.name LIKE '%${SqlString.escape(name)}%'` : '';

name可能是用户输入变量,此时需要防止SQL注入。所有用户输入变量都需要直接对其应用SQL注入保护。
在已经用变量构造了一个SQL片段之后,绝对不能提供SQL注入保护。当您构建filterSQL片段,然后尝试稍后插入它时,您正在做的事情……实际上您是在有意地进行SQL注入。
免责声明:使用准备好的语句(或等效技术)将获得比这种转义式保护更高级别的保护。Escape样式的保护是针对SQL注入攻击的最低级别的保护,您可以使用它,并且仍然具有任何保护。
免责声明2:允许用户输入表名的一部分也可能非常危险,而且很难正确转义。
例如,假设有一堆表,tbl_foo_1tbl_foo_99。您希望您的用户能够访问所有这些内容。但如果后来有人添加了一个tbl_foo_secret,会发生什么呢?你猜怎么着?您的用户也可以访问它,因为您允许他们选择自己的表名。或者,如果添加一个完整的架构,tbl_foo_top_secret?它们可以很容易地告诉您表后缀是tbl_foo_top_secret.table_name,您的代码将很好地接受它,因为在这个库中,句点不会转义。因此,您需要添加自己的自定义检查,以确保表名后缀是可接受的。

关于javascript - 参数化动态查询/SQL卫生NodeJS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57382704/

10-15 14:38