二阶 SQL 注入指恶意载荷在首次写入时被转义存储,之后从数据库读出并在另一处未参数化的 SQL 语句中拼接执行。使用 ORM 时若混用原生查询字符串拼接(如 Raw()、extra()),同样会引入此类漏洞。
一、危险的 ORM 原生拼接示例
python
# 危险:用户名注册时被参数化存储,但后续查询使用字符串拼接
def update_profile(username: str, new_email: str):
# 攻击者注册用户名: admin'--
user = User.objects.get(username=username) # 此处安全
# 后续使用 raw 拼接,存储的恶意用户名被二次触发
cursor.execute(f"UPDATE profiles SET email='{new_email}' WHERE username='{user.username}'")
# 安全写法:始终使用参数化查询
def update_profile_safe(username: str, new_email: str):
cursor.execute(
"UPDATE profiles SET email = %s WHERE username = %s",
[new_email, username],
)