SQL 注入
约 4 分钟阅读
最后更新: 2026-09-01
什么是 SQL 注入
SQL 注入是指用户输入未经妥当处理就被嵌入 Web 应用的数据库查询,导致攻击者能够执行任意 SQL 语句的漏洞。危害可能扩大到窃取、篡改、删除数据库中的全部数据,甚至在服务器上执行操作系统命令。在 OWASP Top 10 中,SQL 注入 (CWE-89) 被归入 Injection 类别:2017 年版以 A1:2017-Injection 位列首位,2021 年版为 A03:2021,2025 年版为 A05:2025。
公开论述经由 Web 注入 SQL 的早期文献之一,是 1998 年 12 月《Phrack Magazine》第 54 期刊登的文章《NT Web Technology Vulnerabilities》。该文以 MS SQL Server 6.5 允许批量执行多条语句为例,指出在把网页输入值直接拼接而成的 SQL 语句后面还能再接上另一条 SQL 语句。距这一提醒已过去四分之一个世纪以上,截至 2026 年 8 月,尽管根本性的对策十分明确,因实现疏漏而残留该漏洞的情况仍层出不穷。
攻击原理与类型
SQL 注入发生在应用程序通过字符串拼接构建 SQL 查询时。例如,如果登录表单中输入的用户名被直接嵌入 SELECT * FROM users WHERE name = '输入值' 这样的查询中,攻击者输入 ' OR '1'='1 就能使 WHERE 子句始终为真,从而绕过认证。
主要攻击类型
- UNION 型:注入
UNION SELECT获取本不可访问的表中的数据。需要匹配列数和类型,但可以通过错误消息或响应变化推断 - 报错型:故意触发错误,从错误消息中读取数据库信息 (表名、列名、数据)
- 盲注:当错误消息不显示时,利用布尔型条件分支或基于时间的响应差异,逐位提取信息
- 带外 (Out-of-Band):通过 DNS 请求或 HTTP 请求将数据从数据库发送到外部服务器
由于 sqlmap 等自动化工具的存在,即使没有高级技术知识也能检测和利用 SQL 注入。
实际危害与影响范围
SQL 注入的危害并不止于数据被窃取。
- 窃取数据:个人信息、认证凭据、信用卡号等保存在数据库中的所有数据都可能泄露
- 篡改与删除数据:注入
UPDATE或DELETE语句来篡改或删除数据,用DROP TABLE还能删掉整张表 - 绕过身份验证:操纵登录查询,在不知道密码的情况下以任意账户 (包括管理员) 登录
- 夺取服务器控制权:滥用数据库的功能 (MySQL 的
LOAD_FILE、SQL Server 的xp_cmdshell等) 执行操作系统层面的命令
在 OWASP 2025 年版 Top 10 的统计中,SQL 注入 (CWE-89) 的报告频率本身低于 Cross-Site Scripting,但作为影响程度较大的漏洞,已登记超过 1 万 4 千个 CVE。WAF 的检测是有效的辅助手段,不过通过巧妙的编码或插入注释绕过 WAF 的手法也已为人所知,它并不能取代根本性的对策。
根本性防御措施
SQL 注入的根本对策十分明确。只要把 SQL 语句的结构与数据分离的实现方式贯彻到底,就能封堵大部分攻击路径。不过正如 OWASP 所提醒的,即使调用方做了参数化,只要存储过程内部的 PL/SQL 或 T-SQL 仍在做字符串拼接、或通过 EXECUTE IMMEDIATE 执行,漏洞依然存在。
预处理语句 (参数化查询)
把 SQL 语句的结构与数据分离,使用户输入不会被当作 SQL 语法来解释。OWASP Top 10 的 Injection 项目同样把不经过解释器的安全 API 与参数化接口列为首选。主流的数据库访问库都提供了相当于预处理语句的机制,因此把用字符串拼接组装查询的地方替换掉是第一步。需要注意的是,表名、列名这类 SQL 的结构部分无法放入占位符,用转义也保护不了。当排序所用的列名等要由用户输入决定时,应当用允许列表把可接受的取值固定下来。在不得不动态组装的地方使用转义,只能定位为封堵无法参数化部分的辅助手段。
运用 ORM
使用 ORM (Object-Relational Mapping) 后,需要直接编写 SQL 的场合减少,SQL 注入的风险也随之降低。不过在使用 ORM 的原始查询功能或自定义查询时,需要与预处理语句同样的注意。
多层防御
常见误解
- 对输入值进行转义就能防止 SQL 注入
- 转义处理容易出现实现错误,字符编码差异和特殊情况会导致遗漏。预处理语句从根本上将 SQL 结构与数据分离,消除了转义遗漏的风险。应使用预处理语句而非转义。
- NoSQL 数据库不会发生 SQL 注入
- 虽然不会发生 SQL 注入,但存在名为 NoSQL 注入的同类漏洞。在 MongoDB 中,将用户输入直接嵌入 JSON 查询可能导致查询运算符注入。无论数据库类型如何,正确处理用户输入都是必须的。
SQL 注入与 XSS 的比较
SQL 注入
以服务器端数据库为目标。可以窃取、篡改、删除数据。通过预处理语句可从根本上防御。危害影响服务器端数据。
XSS
以客户端浏览器为目标。主要危害包括 Cookie 窃取和会话劫持。通过输出转义和 CSP 进行防御。危害发生在用户的浏览器中。