You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中的二阶SQL注入问题:为何指定代码分支会引发该漏洞?

为什么if分支会引发二阶SQL注入?

先看你的代码片段:

public static boolean jdbcExecute(String query,Statement pstmt, String engineName){ 
    boolean res = false; 
    int dbType = ServerProperty.getReference().getDBType(engineName); 
    PreparedStatement pstmtNew = null; 
    if(pstmt instanceof PreparedStatement){ 
        pstmtNew = (PreparedStatement)pstmt; 
        res = pstmtNew.execute(); // Second order sql injection 
    }else{ 
        res = pstmt.execute(WFSUtil.TO_STRING(query, false, dbType)); // No second order sql injection 
    } 
    return res; 
}

咱们一步步拆解问题:

先搞懂什么是二阶SQL注入

简单说,二阶注入是恶意数据先被存储到系统(比如数据库),之后在某个业务流程中被取出,拼接/用于构造SQL语句并执行时触发的注入。和普通即时触发的注入不同,它有一个“存储-复用”的延迟过程。

if分支的风险点在哪?

  • 外部传入的PreparedStatement不可控:
    这个分支里的pstmt是从方法外部传入的PreparedStatement对象。如果这个对象在创建时,SQL语句是用从数据库/缓存中取出的、之前未被正确过滤的用户输入拼接而成的,风险就埋下来了。

    举个实际场景:假设之前有用户提交了恶意内容'); DROP TABLE users;--,这个内容被存到了数据库里。之后业务代码从数据库取出这个内容,直接拼接到了PreparedStatement的SQL模板中(比如SELECT * FROM orders WHERE user_id = '${从库中取出的内容}'),然后把这个带恶意片段的PreparedStatement传到了当前方法里。

  • 直接执行未校验的PreparedStatement:
    这里直接调用pstmtNew.execute(),没有做任何额外的安全校验或转义处理。当这个PreparedStatement的SQL语句已经包含了之前存储的恶意片段时,执行它就会触发注入——这就是典型的二阶SQL注入场景。

为什么else分支没问题?

else分支里调用了WFSUtil.TO_STRING(query, false, dbType)处理输入的query参数,这个工具方法应该做了SQL特殊字符转义、预编译参数绑定之类的安全处理,把用户输入里的风险字符(比如单引号、分号)转成了数据库能正确识别的普通文本,自然不会触发注入。

内容的提问来源于stack exchange,提问作者Mohd Faizan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:39:25