用ORM框架就真的不会SQL注入了吗? 西门仙仙 提问于 2026-03-13 11:38:19 阅读 55 安全 最近在用Sequelize写Node.js后端,听说ORM能自动防SQL注入,但我还是有点不放心。比如我这样写:Model.findAll({ where: { name: userInput } }),如果userInput是用户直接传过来的字符串,会不会有风险? 之前试过故意传了个' OR '1'='1进去,结果数据库没崩,但不确定是不是Sequelize内部做了处理。有没有可能在某些写法下还是会绕过防护?比如用raw query或者拼接条件的时候? 我来解答 赞 7 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 艳平(打工版) Lv1 兄弟,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人英歌 Lv1 先说结论:正常用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 加载更多 相关推荐 1 回答 47 浏览 用ORM框架就真的不会SQL注入了吗? 我最近在Vue项目里用TypeORM做后端数据查询,听说ORM能防SQL注入,但心里还是没底。比如下面这种写法安全吗? <script setup> import { getReposit... 迷人的晨旭 安全 2026-03-24 16:54:22 2 回答 35 浏览 用ORM就真的不会SQL注入了吗? 我最近在用 Sequelize 写接口,听说 ORM 能防 SQL 注入,但心里还是不踏实。比如下面这种写法: const user = await User.findOne({ where: { i... 迷人的志红 安全 2026-02-25 09:44:19 2 回答 101 浏览 TypeORM里用Raw写SQL会有注入风险吗? 我最近在用TypeORM的Raw函数拼接查询条件,但担心这样会不会有SQL注入漏洞?比如下面这段代码: const users = await getRepository(User) .find({ ... 一家淼 安全 2026-03-06 00:28:21 1 回答 60 浏览 SQLMap测试时怎么判断是否存在SQL注入? 我用 SQLMap 测试一个登录接口,但返回结果不太确定是不是真的有注入点。比如运行 sqlmap -u "http://example.com/login" --data="username=adm... 司空俊鑫 安全 2026-03-25 14:47:24 2 回答 40 浏览 前端传数字ID到后端,做类型检查能防SQL注入吗? 我在写一个用户信息查询功能,前端传了个用户ID给后端接口。听说只要确保这个ID是数字就能防止SQL注入,是真的吗? 我试过在前端用typeof id === 'number'判断,但发现用户还是可以通... a'ゞ翌菡 安全 2026-03-03 20:25:18 1 回答 43 浏览 前端请求后端接口时,错误信息会不会导致SQL注入风险? 我最近在做登录功能,后端用的是Node.js + MySQL。之前听说如果错误信息暴露太多,可能会被用来做SQL注入攻击。我现在catch到数据库错误就直接把err.message返回给前端了,这样是... Des.红辰 安全 2026-03-27 18:08:27 2 回答 67 浏览 用 transform 做动画真的能提升性能吗?为什么我的页面还是卡? 我听说用 transform 做动画不会触发重排,应该更流畅,但我在做一个滑动菜单时还是明显卡顿,是不是哪里写错了? 我试过只用 transform: translateX 来移动元素,也加了 wil... 长孙秀英 优化 2026-03-14 02:40:20 2 回答 33 浏览 存储过程真能防住SQL注入吗?我这样写安全吗? 我在用Node.js调用MySQL的存储过程,听说用存储过程能防SQL注入,但我还是有点不放心。比如我这样拼接参数传进去: CALL getUserInfo(${userId}) 会不会有风险?是不是... UX-米阳 安全 2026-03-12 19:37:18 1 回答 46 浏览 前端如何防止SQL注入时意外暴露敏感信息? 我在做用户登录功能时,后端用了参数化查询防SQL注入,但前端错误提示写得太详细,比如直接显示“用户名或密码错误”,担心被用来暴力探测账户。想隐藏具体错误,但又不能让用户完全不知道哪里出错,这该怎么平衡... Newb.培聪 安全 2026-03-10 20:42:24 2 回答 37 浏览 前端用 Prepared Statement 能防 SQL 注入吗? 我最近在学安全防护,看到说用 Prepared Statement 可以防止 SQL 注入。但我是在写前端代码(比如用 fetch 发请求),那我在前端拼 SQL 字符串然后发给后端,是不是照样会被注... 东方晓萌 安全 2026-02-27 04:52:17
Sequelize的findAll这种写法是安全的,它内部会用参数化查询,你传什么都会当字面量处理,不会拼到SQL里。你试的' OR '1'='1'会被当成name字段的值去查,不会变成注入。
但你说对了,有些写法确实会翻车:
用sequelize.query()直接写原生SQL,如果自己拼接字符串就完蛋。比如:
这种写法跟直接写SQL没区别,该注入还是注入。
还有sequelize.literal()、sequelize.where()这些允许传原始SQL的地方,一不留神就中招。
另外有些人是这样踩坑的:
总结一下:ORM的查询构造器是安全的,但只要你用了raw query或者自己拼接字符串,不管用不用ORM都白搭。记住一条:永远别让用户输入直接进SQL字符串,要么用参数化查询,要么用ORM的查询构造器。
你试的那个
' OR '1'='1没崩,是因为Sequelize内部用的是参数化查询,大概相当于这样:SELECT * FROM users WHERE name = ? -- ' OR '1'='1 会被当作整个字符串传进去,不会被解析成SQL逻辑
所以标准写法
Model.findAll({ where: { name: userInput } })没问题。但这几个地方容易翻车:
1. raw query
这种直接拼字符串的raw query跟手写SQL没区别,该注入还是注入。
2. Sequelize.literal() 或 Sequelize.where()
3. 字符串拼接的where条件
总结一下:ORM的查询构建器是安全的,但一旦你用了raw query、literal()、或者自己拼字符串,那就跟裸写SQL没区别了。懒省事直接拼字符串的话,该注入还是注入。
日常开发尽量用对象形式写where条件,别碰literal(),除非万不得已必须用raw query时记得用参数绑定。