SQL注入原理及防护方案
SQL注入原理
SQL注入是一种通过向应用程序的输入字段插入恶意SQL代码,从而操纵后端数据库查询的攻击方式。其核心原理是应用程序未对用户输入进行严格过滤或转义,直接将其拼接到SQL语句中执行。例如:
-
基础攻击:
用户在登录表单输入' OR '1'='1
,若后端直接拼接成SELECT * FROM users WHERE username = '' OR '1'='1'
,条件恒成立,导致绕过身份验证。 -
联合查询:
攻击者通过UNION SELECT
合并查询结果,窃取敏感数据。例如输入admin' UNION SELECT credit_card FROM users --
,可能泄露信用卡信息。 -
报错注入:
利用数据库错误回显(如CONVERT()
函数类型不匹配),通过错误信息推断表结构或数据内容。 -
布尔盲注:
通过构造1' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1)='a'--
类似的条件,逐字符猜测数据。
防护方案
1. 参数化查询(预编译语句)
- 核心方法:使用占位符(如
?
、@param
)替代直接拼接,由数据库驱动处理参数转义。 - 示例:
python
复制
cursor.execute("SELECT * FROM users WHERE username = %s", (user_input,))
- 优势:彻底阻断SQL代码与数据混淆,是最有效的防护手段。
2. 输入验证与过滤
- 白名单校验:限制输入格式(如邮箱、数字),拒绝非法字符(如
'
、;
)。 - 长度限制:防止超长输入触发缓冲区溢出或资源耗尽。
3. 最小权限原则
- 数据库账号仅授予必要权限(如禁用
DROP TABLE
、FILE
权限),降低攻击影响。
4. 使用ORM框架
- 如Hibernate、Django ORM等,自动参数化查询,减少手动拼接SQL的机会。
5. 避免动态拼接SQL
- 若必须拼接,严格转义特殊字符(如MySQL的
mysqli_real_escape_string()
),但优先选择参数化。
6. 错误信息隐藏
- 禁止向客户端返回详细错误(如“SQL语法错误在第5行”),改用模糊提示(如“系统繁忙”),防止信息泄漏。
7. Web应用防火墙(WAF例如上海云盾云WAF)
- 拦截常见注入特征(如
' OR 1=1 --
),但需定期更新规则。
8. 定期安全审计
- 代码审查关注输入处理逻辑,使用自动化工具(如SQLMap)检测潜在漏洞。
总结
参数化查询是防御SQL注入的根本,其他措施(如输入校验、权限控制)作为补充。开发中需始终遵循“不信任任何外部输入”的原则,避免动态拼接SQL,结合技术与管理手段综合防护。