CodeQL中Source点的实现逻辑与Spring框架污点源分析
字数 1834 2025-10-01 14:05:52

CodeQL中Source点实现逻辑与Spring框架污点源分析

一、Source点基础概念

1.1 SourceNode抽象类

abstract class SourceNode extends DataFlow::Node {
  /** 获取代表威胁模型类型的字符串 */
  abstract string getThreatModel();
}

1.2 ActiveThreatModelSource类

class ActiveThreatModelSource extends DataFlow::Node {
  ActiveThreatModelSource() {
    exists(string kind |
      currentThreatModel(kind) and
      (this.(SourceNode).getThreatModel() = kind or sourceNode(this, kind))
    )
  }
}

二、官方基础Source实现

2.1 RemoteFlowSource远程流源

abstract class RemoteFlowSource extends SourceNode {
  abstract string getSourceType();
  override string getThreatModel() { result = "remote" }
}

2.2 SpringServletInputParameterSource实现

private class SpringServletInputParameterSource extends RemoteFlowSource {
  SpringServletInputParameterSource() {
    this.asParameter() = any(SpringRequestMappingParameter srmp | srmp.isTaintedInput())
  }
  override string getSourceType() { result = "Spring servlet input parameter" }
}

2.3 LocalUserInput本地用户输入

abstract class LocalUserInput extends UserInput {
  override string getThreatModel() { result = "local" }
}

private class DbInput extends LocalUserInput {
  DbInput() { sourceNode(this, "database") }
  override string getThreatModel() { result = "database" }
}

三、威胁模型配置系统

3.1 威胁模型配置谓词

extensible predicate threatModelConfiguration(string kind, boolean enable, int priority);
extensible private predicate threatModelGrouping(string kind, string group);

3.2 currentThreatModel实现逻辑

predicate currentThreatModel(string kind) {
  threatModelEnabled(kind)
  or
  not knownThreatModel(kind) and threatModelEnabled("all")
}

3.3 配置示例

# codeql-config.yml
threat-models:
  - remote        # 启用远程威胁源
  - local         # 启用本地威胁源
  - commandargs   # 启用命令行参数
  - environment   # 启用环境变量
  - file          # 启用文件源
  - database      # 启用数据库源

四、Spring框架Source点分析

4.1 Spring控制器相关类定义

4.1.1 Controller注解识别

class SpringControllerAnnotation extends AnnotationType {
  SpringControllerAnnotation() {
    this.hasQualifiedName("org.springframework.stereotype", "Controller")
    or
    this.getAnAnnotation().getType() instanceof SpringControllerAnnotation
  }
}

4.1.2 Controller类识别

class SpringController extends Class {
  SpringController() { 
    this.getAnAnnotation().getType() instanceof SpringControllerAnnotation 
  }
}

4.1.3 Controller方法识别

abstract class SpringControllerMethod extends Method {
  SpringControllerMethod() { 
    this.getDeclaringType() instanceof SpringController 
  }
}

4.2 SpringRequestMappingParameter污点分析

4.2.1 isTaintedInput核心逻辑

predicate isTaintedInput() {
  this.isExplicitlyTaintedInput()
  or
  not this.isNotDirectlyTaintedInput()
}

4.2.2 明确的用户输入(显式taint)

  1. 参数类型为InputStream或Reader:可直接读取请求体内容
  2. 特定注解标记的参数(SpringServletInputAnnotation):
    • @RequestParam
    • @RequestBody
    • @RequestHeader
    • @CookieValue
    • @PathVariable
  3. 参数类型为HttpEntity:包含请求体和头部信息
  4. 参数上有@RequestAttribute或@SessionAttribute

4.2.3 隐式的用户输入(隐式taint)

  1. 非特殊类型参数:不在排除列表中的参数
  2. 基本类型参数:视为隐式@RequestParam
  3. 复杂对象参数:视为隐式@ModelAttribute

4.2.4 例外情况(不视为taint)

以下类型的参数不会被标记为污点源:

参数类型 说明
ServletRequest/Response 请求响应对象
HttpSession 会话对象
Principal 认证主体
Locale/TimeZone/ZoneId 国际化时区对象
OutputStream/Writer 输出流对象
RedirectAttributes 重定向属性
Errors 错误验证对象
Pageable/Model/ModelMap Spring特定对象

五、实战应用与测试

5.1 Source点定义方式

5.1.1 使用官方默认规则

predicate isSource(DataFlow::Node src) { 
  src instanceof ActiveThreatModelSource 
}

5.1.2 自定义Spring参数规则

predicate isSource(DataFlow::Node src) { 
  src.asParameter() = any(SpringRequestMappingParameter srmp | srmp.isTaintedInput())
}

5.2 库模型与框架检测结合

CodeQL采用双重检测策略:

  1. 库模型检测:对ServletRequest.getParameter()等通用节点定义
  2. 框架特定检测:对Spring等框架的特殊场景定义

5.3 常见问题与解决方案

5.3.1 ServletRequest处理

问题:高版本Jakarta Servlet API兼容性
解决方案:更新库模型定义,支持新旧版本

5.3.2 基本类型误报

问题:int等基本类型可能产生误报
解决方案:通过净化流(isBarrier)进行过滤

5.3.3 RPC场景覆盖

问题:现有规则对RPC场景支持不足
解决方案:自定义RPC框架的Source点定义

六、总结与最佳实践

6.1 核心要点总结

  1. 威胁模型配置:通过currentThreatModel控制激活的Source类型
  2. 多层次检测:结合通用库模型和框架特定检测
  3. 精细化的污点判断:Spring参数的isTaintedInput实现细致入微

6.2 企业级应用建议

  1. 规则定制:根据企业技术栈自定义Source点规则
  2. 持续优化:关注官方更新,及时修复已知问题
  3. 多框架支持:扩展支持Dubbo、gRPC等RPC框架
  4. 误报处理:建立完善的净化流体系,减少误报

6.3 未来发展展望

  1. 更多框架支持:覆盖微服务、云原生等新兴框架
  2. 智能分析:结合机器学习优化污点分析准确性
  3. 生态整合:与CI/CD、IDE等开发工具深度集成

通过深入理解CodeQL的Source点实现逻辑和Spring框架的污点分析机制,可以构建更加准确和高效的安全检测体系,为企业应用安全提供有力保障。

CodeQL中Source点实现逻辑与Spring框架污点源分析 一、Source点基础概念 1.1 SourceNode抽象类 1.2 ActiveThreatModelSource类 二、官方基础Source实现 2.1 RemoteFlowSource远程流源 2.2 SpringServletInputParameterSource实现 2.3 LocalUserInput本地用户输入 三、威胁模型配置系统 3.1 威胁模型配置谓词 3.2 currentThreatModel实现逻辑 3.3 配置示例 四、Spring框架Source点分析 4.1 Spring控制器相关类定义 4.1.1 Controller注解识别 4.1.2 Controller类识别 4.1.3 Controller方法识别 4.2 SpringRequestMappingParameter污点分析 4.2.1 isTaintedInput核心逻辑 4.2.2 明确的用户输入(显式taint) 参数类型为InputStream或Reader :可直接读取请求体内容 特定注解标记的参数 (SpringServletInputAnnotation): @RequestParam @RequestBody @RequestHeader @CookieValue @PathVariable 参数类型为HttpEntity :包含请求体和头部信息 参数上有@RequestAttribute或@SessionAttribute 4.2.3 隐式的用户输入(隐式taint) 非特殊类型参数 :不在排除列表中的参数 基本类型参数 :视为隐式 @RequestParam 复杂对象参数 :视为隐式 @ModelAttribute 4.2.4 例外情况(不视为taint) 以下类型的参数不会被标记为污点源: | 参数类型 | 说明 | |---------|------| | ServletRequest/Response | 请求响应对象 | | HttpSession | 会话对象 | | Principal | 认证主体 | | Locale/TimeZone/ZoneId | 国际化时区对象 | | OutputStream/Writer | 输出流对象 | | RedirectAttributes | 重定向属性 | | Errors | 错误验证对象 | | Pageable/Model/ModelMap | Spring特定对象 | 五、实战应用与测试 5.1 Source点定义方式 5.1.1 使用官方默认规则 5.1.2 自定义Spring参数规则 5.2 库模型与框架检测结合 CodeQL采用双重检测策略: 库模型检测 :对 ServletRequest.getParameter() 等通用节点定义 框架特定检测 :对Spring等框架的特殊场景定义 5.3 常见问题与解决方案 5.3.1 ServletRequest处理 问题:高版本Jakarta Servlet API兼容性 解决方案:更新库模型定义,支持新旧版本 5.3.2 基本类型误报 问题:int等基本类型可能产生误报 解决方案:通过净化流(isBarrier)进行过滤 5.3.3 RPC场景覆盖 问题:现有规则对RPC场景支持不足 解决方案:自定义RPC框架的Source点定义 六、总结与最佳实践 6.1 核心要点总结 威胁模型配置 :通过 currentThreatModel 控制激活的Source类型 多层次检测 :结合通用库模型和框架特定检测 精细化的污点判断 :Spring参数的 isTaintedInput 实现细致入微 6.2 企业级应用建议 规则定制 :根据企业技术栈自定义Source点规则 持续优化 :关注官方更新,及时修复已知问题 多框架支持 :扩展支持Dubbo、gRPC等RPC框架 误报处理 :建立完善的净化流体系,减少误报 6.3 未来发展展望 更多框架支持 :覆盖微服务、云原生等新兴框架 智能分析 :结合机器学习优化污点分析准确性 生态整合 :与CI/CD、IDE等开发工具深度集成 通过深入理解CodeQL的Source点实现逻辑和Spring框架的污点分析机制,可以构建更加准确和高效的安全检测体系,为企业应用安全提供有力保障。