我用Sequelize的sequelize.query()执行原生SQL,但用户输入会拼接到查询里,担心有SQL注入风险。比如下面这样写是不是不安全?
const userId = req.query.id;
const result = await sequelize.query(<code>SELECT * FROM users WHERE id = ${userId}</code>);
我知道Sequelize模型方法自带参数化,但原生查询该怎么正确传参才安全?试过直接拼字符串,但怕被注入。
第一种是位置参数,用问号占位,参数放数组里:
第二种是命名参数,用:name占位,参数放对象里:
这两种方式Sequelize底层都会做参数化处理,相当于预编译SQL语句,用户输入会被当作纯数据处理而不是SQL代码。
另外有个细节要注意,如果查询特别复杂需要拼接SQL片段,可以用sequelize.escape()来转义输入:
不过能用参数化就尽量用参数化,escape是最后的选择。后端处理用户输入永远要多留个心眼。
两种安全写法:
1. 用问号占位符:
2. 用命名参数(适合复杂查询):
Sequelize会自动帮你做参数转义。我平时都这么用,还没被注入过。其实ORM文档里都有写,就是很多人不看(摊手)