Web安全之SQL注入攻击与防御详解
字数 1230 2025-11-10 11:09:41
Web安全之SQL注入攻击与防御详解
一、SQL注入攻击概述
SQL注入(SQL Injection)是一种将恶意SQL代码插入到应用程序的输入参数中,欺骗服务器执行非预期SQL命令的Web安全漏洞。攻击者可通过此漏洞绕过身份验证、窃取、篡改或删除数据库中的数据。例如,用户登录表单中的用户名输入框若未经过滤,攻击者可能输入' OR '1'='1来构造永真条件,非法登录系统。
二、SQL注入攻击原理与步骤
-
漏洞成因:
- 应用程序直接拼接用户输入到SQL语句中(如:
"SELECT * FROM users WHERE username='" + input + "'")。 - 未对用户输入进行合法性校验或参数化处理。
- 应用程序直接拼接用户输入到SQL语句中(如:
-
攻击流程:
- 探测漏洞:在输入框提交特殊字符(如单引号
')观察是否报错(如数据库错误信息泄露)。 - 推断结构:通过报错信息或布尔盲注(如
' AND 1=1 --与' AND 1=2 --的页面差异)推测SQL语句结构。 - 注入攻击:联合查询(UNION)、报错注入、时间盲注等方式获取数据。
示例:
-- 原SQL:SELECT id, name FROM products WHERE category = 'input' -- 攻击输入:' UNION SELECT username, password FROM users -- -- 最终执行:SELECT ... WHERE category = '' UNION SELECT username, password FROM users -- ' - 探测漏洞:在输入框提交特殊字符(如单引号
三、SQL注入类型与案例
-
联合查询注入:
- 利用
UNION合并恶意查询到原SQL中,直接返回额外数据。 - 前提:需知原查询的列数(通过
ORDER BY n试探)。
- 利用
-
布尔盲注:
- 当页面无明确报错时,通过条件语句(如
' AND SUBSTRING(database(),1,1)='a' --)观察页面真假状态差异。
- 当页面无明确报错时,通过条件语句(如
-
时间盲注:
- 利用数据库延时函数(如MySQL的
SLEEP(5))判断条件真假。 - 示例:
' AND IF(1=1, SLEEP(5), 0) --。
- 利用数据库延时函数(如MySQL的
-
报错注入:
- 故意触发数据库报错(如MySQL的
extractvalue(1, concat(0x7e, version())))在错误信息中泄露数据。
- 故意触发数据库报错(如MySQL的
四、SQL注入防御策略
-
参数化查询(首选):
- 使用预编译语句(Prepared Statements)分离SQL逻辑与数据,确保输入始终被当作参数处理。
- 示例(Java):
String sql = "SELECT * FROM users WHERE username = ?"; PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, input); // 输入自动转义
-
输入验证与过滤:
- 白名单校验:对数据类型、格式(如邮箱、数字)严格限制。
- 避免黑名单过滤(如简单替换
'为''),可能被绕过(如Unicode编码)。
-
最小权限原则:
- 数据库账户按需分配权限(如禁止普通应用使用
DROP、FILE等高危操作)。
- 数据库账户按需分配权限(如禁止普通应用使用
-
错误信息隐藏:
- 关闭数据库详细错误回显,使用通用提示页避免信息泄露。
-
Web应用防火墙(WAF):
- 部署WAF检测和拦截常见注入特征(如
UNION、SLEEP等关键词)。
- 部署WAF检测和拦截常见注入特征(如
五、进阶防御:ORM框架与安全工具
- 使用ORM(如Hibernate、Sequelize)自动参数化查询,减少手写SQL风险。
- 定期进行安全扫描(如SQLMap工具模拟检测)与代码审计。
通过以上分层防御策略,可显著降低SQL注入风险,保障数据安全。