首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数化动态查询/ SQL卫生NodeJS

问参数化动态查询/ SQL卫生NodeJS
EN

Stack Overflow用户
提问于 2019-08-06 19:21:47
回答 1查看 1.4K关注 0票数 1

我对节点相当陌生,在使用sqlstring的动态参数化查询方面存在问题。

下面的代码的问题是,过滤器是可选的,取决于用户传递给函数的内容,因此它们的顺序可以改变(使得很难单独传递每个过滤器参数)。据我所知,Sqlstring使用顺序来确定哪个参数与适当的问号匹配。

因此,我可以一次将所有过滤器传递给Sqlstring,但是如果没有有效的过滤器,那么我只需要为filters变量留出一个空字符串,这将引发sql语法错误。

代码语言:javascript
复制
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);
}

它生成的查询如下所示:

代码语言:javascript
复制
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;

有更好的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-06 20:03:01

如果你看一下sqlstring npm页面,它就会提到SqlString.format

这看起来类似于MySQL中准备好的语句,但是它实际上只是在内部使用相同的SqlString.escape()方法。

适当地使用SqlString.escape会更好。

但问题是,您是,而不是,您需要在需要的地方防止SQL注入。例如,在这条语句中,您的应该具有注入保护,而您没有注入保护。

代码语言:javascript
复制
filter += name !== undefined ? ` AND a.name LIKE '%${SqlString.escape(name)}%'` : '';

name可能是用户输入变量,您需要在这一点上保护它不受SQL注入的影响。所有用户输入变量都需要直接应用于的注入保护。

在使用变量构造SQL片段之后,绝对不能提供SQL注入保护。当您构建您的filter SQL片段并在以后尝试插入它时所做的事情……这实际上是您在进行有意的SQL注入。

免责声明:使用准备好的语句(或等效技术)获得比这种转义式保护更高的保护级别。逃逸样式保护是防范SQL注入攻击的最低级别,您可以使用这种保护,而且仍然有任何保护。

免责声明2:允许用户输入部分表名的也非常危险,很难正确地转义。

例如,假设您有一堆表,tbl_foo_1通过tbl_foo_99。您希望您的用户能够访问所有这些。但是,如果后来有人添加了一个tbl_foo_secret,会发生什么呢?你猜怎么着?您的用户也可以访问它,因为您允许他们选择自己的表名。或者,如果您添加了一个完整的模式,tbl_foo_top_secret?它们可以很容易地告诉您,表后缀是tbl_foo_top_secret.table_name,您的代码会很好地接受它,因为在这个库中,周期不是转义的。因此,您需要添加自己的自定义检查,以确保表名后缀是可接受的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57382704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档