跳到正文
>_ITDITDWeb 安全平台

术语表

什么是 SQL injection(SQLi)——能用输入改写数据库命令的漏洞

SQL injection(SQLi)是一种让用户的输入改写数据库命令(SQL)含义的漏洞。它会导致数据被读取、被篡改、被全部删除。本文用图解讲解原理,并以防御视角(不公开攻击手法)介绍真正有效的防御:占位符=prepared statement、ORM、最小权限数据库。

发布于 2026-06-08 更新于 2026-06-08 1 分钟阅读

「在搜索框里输入的文字,竟成了数据库『命令的一部分』」——这就是 SQL injection。本文讲解它的原理与可靠的防御方法(不公开攻击手法)。

为什么会发生(原理)

危险的根源在于用字符串拼接来组装 SQL 语句。一旦「把输入直接混进语句里」,输入就会越过「值」的边界,作为「命令」生效。

✗ 字符串拼接(危险)

把输入直接拼进语句 → 输入可能被解释为命令的一部分

✓ 占位符(安全)

值作为「数据」传入 ? / $1 等占位框 → 始终只是值

用字符串拼接混入输入,就会越过「值的边界」、改变命令的含义。而占位符能让值始终只是值。

受害范围是「那个数据库连接能做的一切」。一旦能触及内部数据库,它就和 RCESSRF 并列,成为大规模泄露的典型入口。

防御

1

使用占位符(prepared statement)(最重要)

组装 SQL 时不使用字符串拼接。值通过 ? / 具名参数等作为「数据」传入。仅此一项,就能让这一类漏洞几乎消失。

2

交给 ORM/查询构建器处理

多数 ORM 默认使用占位符。越少自己写裸 SQL 就越安全。即便必须写裸 SQL,也务必参数化。

3

把数据库用户设为最小权限

不要给应用用的数据库用户多余的权限(DROP、其他表、管理操作)。即使万一被攻破,也能缩小受害范围。

4

输入校验作为「辅助」

对类型、长度、格式做校验是有效的,但不要把它单独当作防御的主力。它只是占位符之上的额外加强。

本站观点:从根本上不再「手工拼裸 SQL」

SQLi 存在已久却始终消除不掉——原因在于「图方便,就把输入混进语句里」。本站的立场很明确:不制造把值用字符串拼接放进 SQL 的场景。只要把占位符或 ORM 设为默认,这个漏洞就会在设计阶段从结构上消失。请不要走「靠手动转义硬扛」的方向。

盲点:占位符只能传「值」

占位符并非万能。它能传的只有 ,而对**表名、列名、ORDER BY 的方向(升序/降序)**这类「查询的结构」无能为力。

当你想把这部分做成动态的(例如:让用户选择「排序键」「筛选列」),不要把输入直接放进 SQL,而应从事先确定的许可清单里挑出对应的正规名称。「排序列」「过滤列」正是那种容易因「以为占位符已经守住了」而麻痹大意的典型盲点

接下来阅读

FAQ

QSQL injection 会造成什么后果?
A

攻击者可以改变数据库查询的含义,读取本不该看到的数据、篡改数据,最糟时甚至能全部删除或绕过身份验证。它是个人信息大规模泄露的典型原因之一。

Q最可靠的防御是什么?
A

就是「用占位符(prepared statement)传值」。组装 SQL 语句时不使用字符串拼接,值始终作为「数据」通过另一条路径传入。这样输入就没有被当作命令解释的余地了。多数 ORM 默认就这么做。

Q对输入做转义就够了吗?
A

手动转义容易遗漏,不推荐。真正有效的还是占位符。此外要把数据库用户设为最小权限,以备万一来缩小受害范围。