codeql的一个测试

codeql规则版本v2.22.1

说明:当前只是检测Parameter为HttpServletRequest对象最终调用startsWith方法则命中污点链路,这其中有以下几点

  • 是否位于过滤器拦截器判断?所有绕过基本发生在过滤器拦截器;(添加相应逻辑有问题)
  • Spring boot版本2.3.1以下的判断,codeql的组件确认这个东西还没有测试过。不清楚是否可用(semmle.code.xml.MavenPom)
  • 中间链路问题这个检测过于简单。会存在误报的情况;

/**
 * @name Spring Boot path traversal bypass in authorization checks
 * @description Detects potential path traversal bypass in Spring Boot authorization filters
 * @kind path-problem
 * @problem.severity error
 * @security-severity 8.0
 * @precision high
 * @id java/spring/path-traversal-auth-bypass
 * @tags security
 *       external/cwe/cwe-22
 *       external/cwe/cwe-863
 */

import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.xml.MavenPom
import RequestToStartTaintFlow::PathGraph


class RequestParameter extends Parameter {
  RequestParameter() {
    this.getType().(RefType).getASupertype*().hasQualifiedName("javax.servlet.http","HttpServletRequest") or
    this.getType().(RefType).getASupertype*().hasQualifiedName("jakarta.servlet.http","HttpServletRequest")
  }
}


class RequestUriAccess extends MethodCall {
  RequestUriAccess() {
    this.getMethod().hasName("getRequestURI") or
    this.getMethod().hasName("getServletPath") or
    this.getMethod().hasName("getPathInfo")
  }
}



class StartsWithCall extends MethodCall {
  StartsWithCall() {
    this.getMethod().hasName("startsWith")
  }
}




module RequestToStartsWithConfig implements DataFlow::ConfigSig{
  int fieldFlowBranchLimit() { result = 100000 }

    predicate isSource(DataFlow::Node source) {
    // source是请求对象参数
    source.asParameter() instanceof RequestParameter
  }

   predicate isSink(DataFlow::Node sink) {
    // sink是startsWith方法调用的qualifier
    exists(StartsWithCall startsWithCall |
      sink.asExpr() = startsWithCall.getQualifier() 
    )
  }

   predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
    // 添加通过getRequestURI()等方法的数据流步骤
    exists(RequestUriAccess uriAccess |
      node1.asExpr() = uriAccess.getQualifier() and
      node2.asExpr() = uriAccess
    ) 
  }

}

module RequestToStartTaintFlow = TaintTracking::Global<RequestToStartsWithConfig>;

from RequestToStartTaintFlow::PathNode source, RequestToStartTaintFlow::PathNode sink
where 
  RequestToStartTaintFlow::flowPath(source, sink)
select sink, source, sink,
  "潜在的路径遍历绕过风险:在过滤器/拦截器中直接使用request.getRequestURI().startsWith()进行权限检查," +
  "可能被路径遍历攻击绕过(如:/no-auth/..;/protected)。建议使用路径标准化处理。"
posted @ 2025-08-05 09:30  Yg~  阅读(59)  评论(0)    收藏  举报