Skip to content

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):无回显时通过页面差异或延时判断。
  • 堆叠查询:执行多条语句,危害更大。

防御方案

  1. 参数化查询(预编译) —— 最彻底的解决方案:
python
# 安全:参数化
cursor.execute("SELECT * FROM users WHERE name = %s", (username,))
  1. ORM 框架:如 SQLAlchemy、Hibernate,默认使用参数绑定。
  2. 最小权限:数据库账号仅授予必要权限,禁止 DROP/FILE 等。
  3. 输入校验与白名单:对类型、长度、字符集做严格限制。
  4. WAF / RASP:作为纵深防御的补充层。

⚠️ 所有示例仅用于授权环境下的安全研究与教学,请勿在未授权系统上测试。

SecLab 网络安全博客 · 内容仅供安全研究与学习,请勿用于未授权活动