### 二次注入漏洞原理

我们通过一个经典的案例来解释这个过程

假设有一个网站，允许用户注册并修改个人信息，其中包含用户名

**第一阶段：数据注入**

1. **用户注册**：注册时，应用对用户名进行了严格的过滤，阻止了单引号和一些 SQL 关键字
2. **攻击者构造恶意用户名**：攻击者注册一个名为 `test' and 1=1--` 的账户。由于注册时的过滤机制，攻击者无法直接注入
3. **攻击者换一种方式**：攻击者注册一个名为 `test` 的账户。然后，在修改用户名的功能中，他将用户名修改为 `test' and 1=1--`
4. **应用处理**：假设应用在**更新操作**时对用户输入做了严格的过滤，但数据库中的**新增操作**没有。攻击者在第一次新增时，输入一个看似无害的用户名，例如 `test`

**漏洞的真正利用**：

现在，假设应用有一个功能，允许用户修改自己的个人信息，而这个功能在设计时存在缺陷

- **正常的修改用户信息 SQL 语句**：

  ```sql
  UPDATE users SET email = 'user@example.com' WHERE username = 'test';
  ```
  
- **攻击者如何利用**：

  1. **第一次注入**：攻击者注册一个名为 `test` 的账户。这个数据被安全地存储在数据库中
  2. **第二次注入**：攻击者找到一个功能，例如“修改评论”，而这个功能会将评论内容与用户名关联起来。假设评论表是 `comments`，并且 `username` 列没有做任何过滤

  攻击者提交了一条评论，内容为 `' or 1=1--`。数据库执行了如下语句：

  ```sql
  INSERT INTO comments (username, content) VALUES ('test', '' or 1=1--');
  ```
  
  此时，恶意数据 `' or 1=1--` 被安全地存储在了 `comments` 表中

  1. **触发漏洞**：现在，应用中有一个**管理员审核评论**的功能。管理员点击审核按钮后，后端会执行一个不安全的查询，例如：

  ```sql
  SELECT * FROM comments WHERE content = '' or 1=1--';
  ```

  这条查询语句由于没有对 `content` 字段进行二次过滤，导致 `or 1=1--` 被当作 SQL 语句的一部分，从而绕过了原本的逻辑，直接获取了 `comments` 表中的所有数据，甚至可以被进一步利用进行数据泄露或篡改