52 lines
3.1 KiB
Markdown
52 lines
3.1 KiB
Markdown
### 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` 权限,不要给它 `INSERT`、`UPDATE` 或 `DELETE` 权限
|
||
|
||
- **好处**:即使攻击者成功注入了 SQL 代码,也无法执行超出该账户权限范围的操作,如删除整个数据库
|
||
|
||
|
||
|
||
**5. 错误信息处理**
|
||
|
||
不要向用户暴露详细的数据库错误信息。攻击者可以利用这些信息来了解数据库结构、版本等,从而更容易发起下一次攻击
|
||
|
||
- **正确做法**:当数据库查询失败时,只向用户显示一个通用的、友好的错误页面,并在后台日志中记录详细信息,供开发者排查
|
||
|
||
**6. 使用 Web 应用防火墙(WAF)**
|
||
|
||
WAF 可以在 Web 应用之前对 HTTP 请求进行过滤和拦截,它可以识别并阻止包含 SQL 注入特征的恶意请求
|
||
|
||
- **优点**:
|
||
- **全面保护**:可以为整个应用提供一层额外的保护
|
||
- **实时拦截**:在攻击到达应用之前就将其阻止
|
||
- **局限性**:
|
||
- WAF 的规则可能需要不断更新,以应对新的攻击方式
|
||
- 可能会有误报,影响正常用户的访问 |