SQL注入攻击与防护(进阶篇)
字数 1061 2025-11-24 04:42:30

SQL注入攻击与防护(进阶篇)

描述
SQL注入是一种将恶意SQL代码插入到应用程序输入参数中,从而操纵后端数据库的攻击技术。进阶篇将深入探讨盲注、时间盲注、堆叠查询等复杂技术,以及ORM注入、二次注入等现代变种。

解题过程

  1. SQL注入原理回顾

    • 根本原因:用户输入被直接拼接到SQL查询语句中,且未经过滤或转义。
    • 示例:SELECT * FROM users WHERE username = '${input}',若输入admin' OR '1'='1,查询变为永真条件。
  2. 进阶注入技术分类

    • 盲注(Blind SQLi)
      • 场景:页面不返回具体数据,但根据查询真假显示不同行为(如“存在/不存在”)。
      • 方法:通过布尔逻辑(如AND 1=1/AND 1=2)或条件触发延迟(时间盲注)逐字符提取数据。
    • 堆叠查询(Stacked Queries)
      • 场景:支持多条SQL语句执行(如MySQL的mysqli_multi_query)。
      • 风险:攻击者可插入; DROP TABLE users等破坏性语句。
    • ORM注入
      • 成因:误用ORM(如Hibernate)的原始查询或不当参数绑定,例如HQL中WHERE name = '${input}'仍可被注入。
    • 二次注入
      • 流程:恶意输入先被存入数据库,后续从数据库取出时被拼接到查询中,绕过初次过滤。
  3. 防护机制深度剖析

    • 参数化查询(核心防御)
      • 原理:将输入作为参数传递而非拼接,数据库区分代码与数据。
      • 示例:
        -- 错误方式  
        query = "SELECT * FROM users WHERE id = " + userInput;  
        -- 正确方式(使用占位符)  
        query = "SELECT * FROM users WHERE id = ?";  
        preparedStatement.setInt(1, userInput);  
        
    • 输入验证与白名单
      • 对数字参数校验范围,对字符串使用正则表达式限制字符集(如仅允许字母数字)。
    • 最小权限原则
      • 数据库账户仅授予必要权限(如禁止执行DROPFILE操作)。
    • ORM安全实践
      • 避免拼接HQL/JPQL,使用命名参数(如Hibernate的setParameter方法)。
  4. 实战案例:时间盲注检测

    • 步骤:
      1. 判断注入点:输入id=1' AND SLEEP(5)-- ,观察响应是否延迟。
      2. 逐字符提取数据:
        id=1' AND IF(SUBSTR(database(),1,1)='a', SLEEP(5), 0)--  
        
      3. 自动化工具:使用Sqlmap的--time-sec参数指定延迟时间。
  5. 现代框架中的陷阱

    • 即使使用ORM,以下情况仍可能失效:
      • 动态表名/列名拼接(如"SELECT * FROM " + tableName)。
      • 原生SQL片段未参数化(如JPA的@Query中拼接字符串)。

通过结合严格编码规范、工具扫描(如SAST/DAST)和纵深防御,可系统性规避SQL注入风险。

SQL注入攻击与防护(进阶篇) 描述 SQL注入是一种将恶意SQL代码插入到应用程序输入参数中,从而操纵后端数据库的攻击技术。进阶篇将深入探讨盲注、时间盲注、堆叠查询等复杂技术,以及ORM注入、二次注入等现代变种。 解题过程 SQL注入原理回顾 根本原因:用户输入被直接拼接到SQL查询语句中,且未经过滤或转义。 示例: SELECT * FROM users WHERE username = '${input}' ,若输入 admin' OR '1'='1 ,查询变为永真条件。 进阶注入技术分类 盲注(Blind SQLi) : 场景:页面不返回具体数据,但根据查询真假显示不同行为(如“存在/不存在”)。 方法:通过布尔逻辑(如 AND 1=1 / AND 1=2 )或条件触发延迟(时间盲注)逐字符提取数据。 堆叠查询(Stacked Queries) : 场景:支持多条SQL语句执行(如MySQL的 mysqli_multi_query )。 风险:攻击者可插入 ; DROP TABLE users 等破坏性语句。 ORM注入 : 成因:误用ORM(如Hibernate)的原始查询或不当参数绑定,例如HQL中 WHERE name = '${input}' 仍可被注入。 二次注入 : 流程:恶意输入先被存入数据库,后续从数据库取出时被拼接到查询中,绕过初次过滤。 防护机制深度剖析 参数化查询(核心防御) : 原理:将输入作为参数传递而非拼接,数据库区分代码与数据。 示例: 输入验证与白名单 : 对数字参数校验范围,对字符串使用正则表达式限制字符集(如仅允许字母数字)。 最小权限原则 : 数据库账户仅授予必要权限(如禁止执行 DROP 、 FILE 操作)。 ORM安全实践 : 避免拼接HQL/JPQL,使用命名参数(如Hibernate的 setParameter 方法)。 实战案例:时间盲注检测 步骤: 判断注入点:输入 id=1' AND SLEEP(5)-- ,观察响应是否延迟。 逐字符提取数据: 自动化工具:使用Sqlmap的 --time-sec 参数指定延迟时间。 现代框架中的陷阱 即使使用ORM,以下情况仍可能失效: 动态表名/列名拼接(如 "SELECT * FROM " + tableName )。 原生SQL片段未参数化(如JPA的 @Query 中拼接字符串)。 通过结合严格编码规范、工具扫描(如SAST/DAST)和纵深防御,可系统性规避SQL注入风险。