SQL注入原理与防御
SQL 注入(SQL Injection)是 Web 安全领域最经典、危害也最大的漏洞之一。当应用程序将用户输入直接拼接到 SQL 语句中而未做校验或转义时,攻击者可构造恶意输入改变原语句的语义,进而读取、篡改甚至删除数据库数据。
成因
根本原因是数据与指令未分离。例如下面的危险写法:
python
# 危险:字符串拼接
sql = "SELECT * FROM users WHERE name = '" + username + "'"
cursor.execute(sql)当 username = "admin' -- " 时,拼接后的语句变为:
sql
SELECT * FROM users WHERE name = 'admin' -- '-- 之后的内容被注释,攻击者无需密码即可以 admin 身份登录。
常见利用方式
- 联合查询注入(UNION):通过
UNION SELECT读取其他表数据。 - 报错注入:利用数据库报错回显敏感信息。
- 盲注(Boolean / Time-based):无回显时通过页面差异或延时判断。
- 堆叠查询:执行多条语句,危害更大。
防御方案
- 参数化查询(预编译) —— 最彻底的解决方案:
python
# 安全:参数化
cursor.execute("SELECT * FROM users WHERE name = %s", (username,))- ORM 框架:如 SQLAlchemy、Hibernate,默认使用参数绑定。
- 最小权限:数据库账号仅授予必要权限,禁止
DROP/FILE等。 - 输入校验与白名单:对类型、长度、字符集做严格限制。
- WAF / RASP:作为纵深防御的补充层。
⚠️ 所有示例仅用于授权环境下的安全研究与教学,请勿在未授权系统上测试。