用ORM框架就真的不会SQL注入了吗?

西门仙仙 阅读 55

最近在用Sequelize写Node.js后端,听说ORM能自动防SQL注入,但我还是有点不放心。比如我这样写:Model.findAll({ where: { name: userInput } }),如果userInput是用户直接传过来的字符串,会不会有风险?

之前试过故意传了个' OR '1'='1进去,结果数据库没崩,但不确定是不是Sequelize内部做了处理。有没有可能在某些写法下还是会绕过防护?比如用raw query或者拼接条件的时候?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
艳平(打工版)
兄弟,ORM防注入这事儿吧,得分情况看。

Sequelize的findAll这种写法是安全的,它内部会用参数化查询,你传什么都会当字面量处理,不会拼到SQL里。你试的' OR '1'='1'会被当成name字段的值去查,不会变成注入。

但你说对了,有些写法确实会翻车:

用sequelize.query()直接写原生SQL,如果自己拼接字符串就完蛋。比如:
sequelize.query(SELECT * FROM users WHERE name = '${userInput}')


这种写法跟直接写SQL没区别,该注入还是注入。

还有sequelize.literal()、sequelize.where()这些允许传原始SQL的地方,一不留神就中招。

另外有些人是这样踩坑的:
// 错误示例
const where = { name: userInput } // 这个安全
// 但有人非要写成:
const sql = "SELECT * FROM users WHERE name = '" + userInput + "'" // 找死


总结一下:ORM的查询构造器是安全的,但只要你用了raw query或者自己拼接字符串,不管用不用ORM都白搭。记住一条:永远别让用户输入直接进SQL字符串,要么用参数化查询,要么用ORM的查询构造器。
点赞
2026-03-19 20:08
IT人英歌
先说结论:正常用Sequelize的ORM写法是安全的,但你提到的raw query和某些拼接方式确实有坑。

你试的那个 ' OR '1'='1 没崩,是因为Sequelize内部用的是参数化查询,大概相当于这样:

SELECT * FROM users WHERE name = ? -- ' OR '1'='1 会被当作整个字符串传进去,不会被解析成SQL逻辑

所以标准写法 Model.findAll({ where: { name: userInput } }) 没问题。

但这几个地方容易翻车:

1. raw query
// 危险写法
Model.sequelize.query(SELECT * FROM users WHERE name = '${userInput}')

// 安全写法
Model.sequelize.query('SELECT * FROM users WHERE name = ?', { replacements: [userInput] })


这种直接拼字符串的raw query跟手写SQL没区别,该注入还是注入。

2. Sequelize.literal() 或 Sequelize.where()
// 危险写法
Model.findAll({
where: {
name: Sequelize.literal('${userInput}') // 直接拼进去
}
})

// 或者用Op.like时
Model.findAll({
where: {
name: {
[Op.like]: '%' + userInput + '%' // 尽量避免这样拼接
}
}
})


3. 字符串拼接的where条件
// 危险写法
const whereClause = "name = '" + userInput + "'"
Model.findAll({ where: Sequelize.literal(whereClause) })


总结一下:ORM的查询构建器是安全的,但一旦你用了raw query、literal()、或者自己拼字符串,那就跟裸写SQL没区别了。懒省事直接拼字符串的话,该注入还是注入。

日常开发尽量用对象形式写where条件,别碰literal(),除非万不得已必须用raw query时记得用参数绑定。
点赞 1
2026-03-13 12:03