SQL 注入防御方法

1. 使用预编译语句

这是最有效、也是最推荐的防御方法。预编译语句会先将 SQL 语句发送到数据库进行编译,然后将用户输入作为参数传递给编译好的语句。这样一来,用户输入的数据就无法改变 SQL 语句本身的结构

  • 原理:将 SQL 语句与用户输入的数据分开处理。数据库会把用户输入的内容看作纯粹的数据,而不是可执行的代码
  • 示例
    • 不安全的代码"SELECT * FROM users WHERE username = '" + userInput + "';"
      • 如果 userInput' OR 1=1 --,整个语句就变成了 SELECT * FROM users WHERE username = '' OR 1=1 --;,从而绕过登录验证
    • 安全的预编译语句"SELECT * FROM users WHERE username = ?;"
      • 这里的问号 ? 是一个占位符。无论用户输入什么,都会被当作 username 字段的值来处理,而不是 SQL 代码

2. 对所有用户输入进行严格验证和过滤

永远不要相信用户的任何输入。在将数据送入数据库之前,必须对其进行验证和过滤

  • 白名单验证:只允许特定的字符、格式或值通过。例如,如果某个输入框只接受数字,那么就只允许数字通过
  • 黑名单过滤:禁止某些特定的危险字符或字符串,如单引号 '、分号 ;、双破折号 -- 等。但是,这种方法很容易被绕过,不推荐作为主要的防御手段

3. 使用 ORM 框架

许多现代编程语言的框架都提供了 ORM 工具,例如 Java 的 Hibernate、Python 的 SQLAlchemy、PHP 的 Eloquent。这些框架通常内置了对 SQL 注入的保护机制

  • 优点
    • 安全性:ORM 框架会自动处理参数绑定,将开发者从手动编写安全 SQL 语句的繁琐工作中解放出来
    • 易用性:开发者可以使用面向对象的方式操作数据库,无需直接编写 SQL 语句

4. 最小权限原则

为数据库账户分配最小的权限。一个账户如果只需要读取数据,就只给它 SELECT 权限,不要给它 INSERTUPDATEDELETE 权限

  • 好处:即使攻击者成功注入了 SQL 代码,也无法执行超出该账户权限范围的操作,如删除整个数据库

5. 错误信息处理

不要向用户暴露详细的数据库错误信息。攻击者可以利用这些信息来了解数据库结构、版本等,从而更容易发起下一次攻击

  • 正确做法:当数据库查询失败时,只向用户显示一个通用的、友好的错误页面,并在后台日志中记录详细信息,供开发者排查

6. 使用 Web 应用防火墙(WAF)

WAF 可以在 Web 应用之前对 HTTP 请求进行过滤和拦截,它可以识别并阻止包含 SQL 注入特征的恶意请求

  • 优点
    • 全面保护:可以为整个应用提供一层额外的保护
    • 实时拦截:在攻击到达应用之前就将其阻止
  • 局限性
    • WAF 的规则可能需要不断更新,以应对新的攻击方式
    • 可能会有误报,影响正常用户的访问
Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:13:26

results matching ""

    No results matching ""