SQL 注入是一种攻击技术,攻击者通过在应用程序预期输入数据的地方(如表单字段、URL 参数等)插入(或“注入”)恶意的 SQL 代码片段。当应用程序没有正确处理这些输入,而是将其直接拼接到后端数据库查询语句(SQL)中并执行时,攻击者注入的恶意代码就会被数据库引擎执行。这导致攻击者能够读取、修改、删除数据库中的敏感数据,甚至完全控制数据库服务器。
原理详解
大多数 Web 应用程序需要根据用户输入动态生成 SQL 查询。例如:
用户登录:
SELECT * FROM users WHERE username = '[用户名]' AND password = '[密码]';
商品搜索:
SELECT * FROM products WHERE name LIKE '%[用户输入的搜索词]%';
显示用户资料:
SELECT * FROM profiles WHERE user_id = [用户输入的 ID];
当应用程序信任了用户的输入,没有对这些输入进行严格的验证、过滤或转义处理,就直接将其拼接到 SQL 语句字符串中。
攻击者却不是输入正常的用户名、密码或搜索词,而是输入精心构造的字符串,这些字符串包含 SQL 语法的一部分,旨在改变原始 SQL 语句的逻辑结构。例如:
登录绕过:
正常输入:用户名 alice, 密码 secret123
生成的 SQL:SELECT * FROM users WHERE username = 'alice' AND password = 'secret123';
攻击者输入: 用户名 ' OR '1'='1,密码可以是任意值(如 x)
拼接后的 SQL: SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'x';
详细解释
单引号 ' 闭合了 username 字段值的起始引号。
OR '1'='1' 是一个永远为真的条件('1'='1' 恒等于 true)。
这使得整个 WHERE 子句变为 true OR ... AND ...。由于 OR 的优先级,逻辑上等同于 (true) OR (... AND ...),结果总是 true。
因此,这个查询会返回 users 表中的所有行(通常是第一个用户),攻击者就能以第一个用户的身份登录(无需知道密码)。