网易首页 > 网易号 > 正文 申请入驻

用了ORM就防住SQL注入了?这4个漏洞正等着你

0
分享至

很多开发者默认一件事:项目上了ORM,SQL注入就不再是自己的问题了。但事实是,它没有消失,只是换了个地方藏身。

Sequelize、Prisma、TypeORM、Knex这类ORM会自动把帮你构建的查询参数化,这部分确实没问题。麻烦出在你走出这条安全路径的地方——ORM查询构建器表达不干净的原始查询、动态排序字段,或者随手拿来用的某个辅助函数。这些恰恰是攻击者最先翻找的位置,也最容易被开发者忽略,因为代码库的其余部分看起来都被保护得好好的。


下面聚焦四种这样的模式。每一种都会给出一个能触发漏洞的可运行示例、它为什么可被利用的拆解,以及一个能堵住它的改写版本。

先看清前提

这些示例假设你对Node.js和Express的基础、编写基本SQL查询、ORM的基本用法(所有代码示例都用Sequelize,但这些模式同样适用于Prisma、TypeORM、Knex等)以及HTTP请求/响应周期的工作方式都比较熟悉。

代码示例中,sequelize假定已经是一个初始化好的Sequelize实例,QueryTypes和Op从'sequelize'导入,User和Product是在应用其他地方定义的Sequelize模型。示例使用Sequelize v6+语法,因为这里提到的一些API在不同大版本之间有过变化。你可以把语法适配到自己使用的版本和ORM上。

原始查询的逃生舱

每个主流ORM都为查询构建器表达不干净的查询准备了一个"逃生舱":sequelize.query()、Prisma的$queryRawUnsafe,或者TypeORM的query()。它们的存在有正当理由,比如复杂连接、窗口函数和厂商特定的SQL。问题始于开发者把这个逃生舱当成ORM的其余部分来用,把用户输入直接插进它构建的字符串里。

看一个典型的带过滤条件的报表接口:

  • 从req.query取出region
  • 用模板字符串把region直接拼进SELECT语句
  • 以QueryTypes.SELECT执行并返回JSON

查询构建器根本看不到这个字符串,它被原样交给数据库驱动。一个类似 ?region=' OR '1'='1 的请求会把查询变成恒真条件,表里每一行都会返回,与region无关。更糟的是,因为这段代码身处一个基于ORM的项目里,它往往得不到非ORM代码库中raw mysql.query()调用那样的审视——审查者会假设ORM已经处理好了。

修复方式是把值交给原始查询API本身提供的替换/绑定机制,而不是自己拼字符串。把region作为replacements传入,SQL里用:region占位。修复不是完全避开原始查询——有时候你确实需要它们,而是在绑定机制就在手边时,永远不要手工构建SQL字符串。

无法参数化的标识符

参数化查询保护的是值,它不保护表名、列名或ORDER BY方向这类标识符。这些必须成为SQL字符串本身的一部分。这就是为什么动态排序功能是注入溜回写得不错的ORM代码的最常见入口之一。

看一个典型的可排序列表接口:sortBy从查询字符串直接进入ORDER BY子句,中间没有任何拦截。sortBy看起来只是个无害的UI便利功能,直到有人发送 created_at; DROP TABLE users; -- 。这个具体载荷是否执行取决于你的数据库驱动:Postgres的pg驱动默认会执行这类堆叠语句,而MySQL的mysql2除非显式设置multipleStatements: true,否则会拦截。无论哪种情况,底层问题都一样:你让任意SQL坐在一个本来只该放列名的位置上。

由于标识符不能被绑定为参数,唯一安全的选择是白名单。定义一个允许的排序列数组,检查sortBy是否在其中,不在就回退到默认列。永远不要把用户输入传到标识符位置,哪怕先"消毒"过也不行——标识符的消毒比值的消毒容易出错得多。如果用户输入决定列名或表名,用白名单,不要用消毒。

通过存储数据发起的二阶注入

还有一种更隐蔽的路径:注入不是发生在输入进入系统的当下,而是发生在数据被存下来、之后又被取出使用的时候。用户提交的内容先安全地存进数据库,看起来毫无问题;等到某个后台任务、报表脚本或另一个接口把这条数据读出来,再拼进新的查询里,注入就在那一刻生效了。

这类问题的识别难点在于,出问题的代码和注入的入口往往不在同一个地方,甚至不在同一次请求里。审查输入接口时一切正常,审查消费数据的代码时又看不到恶意载荷的来源。

应对思路和前面一致:任何把存储数据拼进SQL的地方,都要走绑定机制;任何由存储数据决定的标识符位置,都要走白名单。不要因为数据"是自己数据库里的"就默认它可信。

混进普通ORM调用里的原始SQL

第四种模式更贴近日常:原始SQL片段被夹带进看起来完全正常的ORM调用中。开发者可能只是在某个条件里塞了一小段手写SQL,或者用了一个接受字符串的排序、分组参数,整体调用仍然是ORM的形态,于是没人觉得需要额外警惕。

这类写法的危险在于它伪装得很好。代码里没有显眼的sequelize.query(),审查者的注意力自然放松,但用户输入依然可能顺着那个字符串参数进入SQL结构。

处理原则没有变化:值走绑定,标识符走白名单。凡是接受字符串并最终影响SQL结构的地方,都要当成原始查询来对待,而不是当成ORM的安全调用。

四类问题的共同点

把这四种模式放在一起看,会发现它们指向同一个事实:ORM保护的是它替你构建的那部分查询,而不是你绕过它的那部分。原始查询、标识符位置、存储数据的二次使用、夹带的SQL片段,都是这条边界之外的地带。

对应的做法也很集中:值永远通过绑定机制传递,标识符永远通过白名单决定,不要手工拼接SQL字符串,也不要因为数据来自自家数据库就放松警惕。攻击者最先翻找的,正是这些看起来被保护得很好的代码里露出的缝隙。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
比今年还强!安东尼奥重组U23国足,王钰栋搭档布尼亚明,冲击2028年奥运会

比今年还强!安东尼奥重组U23国足,王钰栋搭档布尼亚明,冲击2028年奥运会

小秦哥聊体育
2026-10-02 19:26:55
孙心然震惊世界网球圈,首轮6比1、3比0连赢9局

孙心然震惊世界网球圈,首轮6比1、3比0连赢9局

刘哥谈体育
2026-10-02 11:11:05
拒绝加入詹姆斯字母行列!文班:看到有球员为预测平台宣传很可悲

拒绝加入詹姆斯字母行列!文班:看到有球员为预测平台宣传很可悲

罗说NBA
2026-10-02 05:38:12
痒是大病预警!提醒:3处发痒,不是过敏,或是这4病

痒是大病预警!提醒:3处发痒,不是过敏,或是这4病

健康科普365
2026-10-01 17:35:12
杭州商K集体停业,投资2亿的顶端商K豪华门头一片漆黑

杭州商K集体停业,投资2亿的顶端商K豪华门头一片漆黑

Mr王的饭后茶
2026-09-23 09:32:37
3.4 亿退休人员,有人每月 16000 元退休金是什么概念?

3.4 亿退休人员,有人每月 16000 元退休金是什么概念?

白米饭怎么吃
2026-08-22 22:10:21
莎莎短发亮相首钢园!中国大满贯女单签表出炉,王曼昱陷死亡半区,孙颖莎首轮叶伊恬,1/8决赛或碰桥本帆乃香

莎莎短发亮相首钢园!中国大满贯女单签表出炉,王曼昱陷死亡半区,孙颖莎首轮叶伊恬,1/8决赛或碰桥本帆乃香

影话星宸聊球
2026-10-02 21:01:48
游本昌最后遗容曝光,静卧大厅中央覆盖党旗,胡歌陈龙赶来送别

游本昌最后遗容曝光,静卧大厅中央覆盖党旗,胡歌陈龙赶来送别

洲洲影视娱评
2026-10-01 15:01:13
曾潜水63小时救出12名少年,泰国洞穴救援英雄布朗不幸去世!

曾潜水63小时救出12名少年,泰国洞穴救援英雄布朗不幸去世!

麓谷隐士
2026-10-02 00:05:04
文班亚马又拒绝合同!真够正义的!

文班亚马又拒绝合同!真够正义的!

柚子说球
2026-10-02 09:10:49
轻松拿下中网开门红,萨巴伦卡:你们都在等着看德约科维奇吧

轻松拿下中网开门红,萨巴伦卡:你们都在等着看德约科维奇吧

澎湃新闻
2026-10-02 20:54:12
说谁呢?可能是他!赛后邵佳一语出惊人:也许有的国脚还在想着联赛和亚冠

说谁呢?可能是他!赛后邵佳一语出惊人:也许有的国脚还在想着联赛和亚冠

足球大腕
2026-10-02 23:15:48
前列腺去世的人越来越多!建议:3不喝、2不吃、2坚持,别大意!

前列腺去世的人越来越多!建议:3不喝、2不吃、2坚持,别大意!

健康科普365
2026-10-02 22:30:03
游客在堵车途中遇断网,突然发现前车尾部贴着“连我车载WiFi密码8个8”,车主:车辆有比较强的网络性能,堵车或停靠时经常有人“蹭网”

游客在堵车途中遇断网,突然发现前车尾部贴着“连我车载WiFi密码8个8”,车主:车辆有比较强的网络性能,堵车或停靠时经常有人“蹭网”

农民日报
2026-10-02 20:13:21
成都警方:一男子驾车逆行并辱骂他人被查处

成都警方:一男子驾车逆行并辱骂他人被查处

界面新闻
2026-10-02 17:12:07
北京胡同老人真心话:腾退拿几百万,晚年反而更难了

北京胡同老人真心话:腾退拿几百万,晚年反而更难了

据说说娱乐
2026-10-02 19:19:22
重磅消息突袭!油价大跳水,欧洲股市直线拉升!

重磅消息突袭!油价大跳水,欧洲股市直线拉升!

证券时报
2026-10-02 17:50:08
1959年,印尼总统访日,日本人知道他好色,专门为他安排了一名19岁的绝色艺伎,没想到,就是这个女人,竟然改变了他的一生。

1959年,印尼总统访日,日本人知道他好色,专门为他安排了一名19岁的绝色艺伎,没想到,就是这个女人,竟然改变了他的一生。

回京历史梦
2026-10-01 06:35:14
记者:C罗曾考虑世界杯退出国家队,热苏斯每天打电话说服他留下

记者:C罗曾考虑世界杯退出国家队,热苏斯每天打电话说服他留下

懂球帝
2026-10-02 16:25:27
亚运会还没结束,中国游泳队在这里又摘两金!

亚运会还没结束,中国游泳队在这里又摘两金!

五星体育
2026-10-02 10:45:16
2026-10-02 23:39:00
字节漫游指南
字节漫游指南
有态度网友ytd
225文章数 123关注度
往期回顾 全部

科技要闻

“分手”15天后,华为与赛力斯签约新五年

头条要闻

媒体:澳想攒个大局"抗衡中国" 一看嘉宾名单尴尬了

头条要闻

媒体:澳想攒个大局"抗衡中国" 一看嘉宾名单尴尬了

体育要闻

30天30队·快船:被莱纳德挂在半空的未来?

娱乐要闻

潘玮柏老婆被猜怀二胎 中秋vlog露馅

财经要闻

珠宝黑马爆雷,老板全家跑路泰国!

汽车要闻

方程豹9月热销破4万 首款皮卡鲨鱼将于四季度上市

态度原创

家居
数码
时尚
手机
军事航空

家居要闻

2026建博会(广州) 公装联探展交流活动

数码要闻

英伟达宣布将推出DGX SPARK 64GB 可在本地运行最高1000亿参数AI模型

伊姐十一热推:电视剧《无可替代》;电视剧《雷霆令》......

手机要闻

创维F3 Pro闺蜜机新增12GB RAM + 256GB存储空间版本,6099元

军事要闻

胡塞武装:24小时内沙特空袭也门47次

无障碍浏览 进入关怀版