跳转到内容

SQL注入防护

来自代码酷

SQL注入防护[编辑 | 编辑源代码]

SQL注入(SQL Injection)是一种常见的网络安全漏洞,攻击者通过在用户输入中插入恶意的SQL代码,从而操纵数据库查询,可能导致数据泄露、篡改或删除。本文将详细介绍SQL注入的原理、防护方法以及实际案例。

什么是SQL注入?[编辑 | 编辑源代码]

SQL注入是一种攻击技术,攻击者通过在应用程序的输入字段(如表单、URL参数)中插入SQL代码片段,欺骗后端数据库执行非预期的SQL命令。例如,攻击者可能绕过登录验证、获取敏感数据或删除表。

示例场景[编辑 | 编辑源代码]

假设有一个登录表单,后端使用以下SQL查询验证用户:

SELECT * FROM users WHERE username = '$username' AND password = '$password';

如果用户输入:

  • 用户名:admin' --
  • 密码:任意值(如123

实际执行的SQL变为:

SELECT * FROM users WHERE username = 'admin' --' AND password = '123';

注释符--使后半部分失效,攻击者可能直接以管理员身份登录。

SQL注入的类型[编辑 | 编辑源代码]

  • 联合查询注入(Union-based):通过UNION合并恶意查询。
  • 布尔盲注(Boolean-based):通过条件判断逐字符提取数据。
  • 时间盲注(Time-based):通过延时响应推断数据。
  • 报错注入(Error-based):利用数据库错误信息泄露数据。

防护措施[编辑 | 编辑源代码]

1. 参数化查询(Prepared Statements)[编辑 | 编辑源代码]

使用参数化查询可确保用户输入始终被视为数据而非SQL代码。例如:

# Python示例(使用sqlite3)
import sqlite3
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))

2. 输入验证与过滤[编辑 | 编辑源代码]

  • 白名单验证:仅允许特定字符(如字母、数字)。
  • 转义特殊字符:如将'转为\'(但不如参数化查询可靠)。

3. 最小权限原则[编辑 | 编辑源代码]

数据库用户应仅拥有必要权限(如禁止DROP TABLE)。

4. ORM框架[编辑 | 编辑源代码]

使用ORM(如Django ORM、SQLAlchemy)可自动避免SQL注入:

# Django示例
User.objects.filter(username=username, password=password)

5. 定期更新与漏洞扫描[编辑 | 编辑源代码]

  • 更新数据库和框架以修复已知漏洞。
  • 使用工具(如OWASP ZAP)扫描应用。

实际案例[编辑 | 编辑源代码]

案例1:登录绕过[编辑 | 编辑源代码]

攻击者输入' OR '1'='1作为用户名和密码,导致查询:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '' OR '1'='1';

条件恒为真,返回所有用户数据。

案例2:数据泄露[编辑 | 编辑源代码]

通过联合查询注入获取其他表数据:

SELECT title, body FROM articles WHERE id = 1 UNION SELECT username, password FROM users;

总结[编辑 | 编辑源代码]

SQL注入防护方法对比
方法 优点 缺点
参数化查询 高效、可靠 需修改代码
输入验证 简单易实现 可能遗漏边缘情况
ORM 开发效率高 学习成本

graph TD A[用户输入] --> B{是否过滤/参数化?} B -->|是| C[安全查询] B -->|否| D[SQL注入风险]

防护公式:安全性=参数化查询+输入验证+最小权限