SQL 注入
约 4 分钟阅读
最后更新: 2026-01-22
什么是 SQL 注入
SQL 注入是一种漏洞,当用户输入未经适当处理就被嵌入数据库查询时,攻击者可以执行任意 SQL 语句。它多年来一直位列 OWASP Top 10,是最危险的 Web 漏洞之一,可能导致数据库中所有数据的窃取、篡改、删除,甚至服务器的操作系统命令执行。
自 1998 年首次被公开报告以来,经过四分之一个世纪,SQL 注入至今仍是针对 Web 应用程序的主要攻击手法。尽管根本性的防御措施已经明确,但由于实现上的缺陷,漏洞仍然层出不穷。
攻击原理与类型
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等) 执行操作系统级命令
许多大规模数据泄露事件都涉及 SQL 注入。通过 WAF 检测是有效的辅助措施,但利用巧妙编码和注释插入绕过 WAF 的技术也已为人所知,因此不能替代根本性的防御措施。
根本性防御措施
SQL 注入的根本防御措施是明确的,正确实现后可以完全消除漏洞。
预处理语句 (参数化查询)
将 SQL 语句结构与数据分离,防止用户输入被解释为 SQL 语法。这是最可靠且推荐的防御措施。所有数据库访问库都支持预处理语句。
使用 ORM
使用 ORM (对象关系映射) 可以减少直接编写 SQL 的机会,降低 SQL 注入风险。但在使用 ORM 的原生查询功能或自定义查询时,需要与预处理语句同样的注意。
纵深防御
常见误解
- 对输入值进行转义就能防止 SQL 注入
- 转义处理容易出现实现错误,字符编码差异和特殊情况会导致遗漏。预处理语句从根本上将 SQL 结构与数据分离,消除了转义遗漏的风险。应使用预处理语句而非转义。
- NoSQL 数据库不会发生 SQL 注入
- 虽然不会发生 SQL 注入,但存在名为 NoSQL 注入的同类漏洞。在 MongoDB 中,将用户输入直接嵌入 JSON 查询可能导致查询运算符注入。无论数据库类型如何,正确处理用户输入都是必须的。
SQL 注入与 XSS 的比较
SQL 注入
以服务器端数据库为目标。可以窃取、篡改、删除数据。通过预处理语句可从根本上防御。危害影响服务器端数据。
XSS
以客户端浏览器为目标。主要危害包括 Cookie 窃取和会话劫持。通过输出转义和 CSP 进行防御。危害发生在用户的浏览器中。