CodeQL库学习-SSRF漏洞挖掘
字数 1494 2025-08-06 18:08:11
CodeQL库学习:SSRF漏洞挖掘
1. CodeQL简介
CodeQL是GitHub开发的语义代码分析引擎,它将代码转换为可查询的数据库,允许开发者编写查询来发现代码中的漏洞模式。主要特点包括:
- 支持多种语言:Java, JavaScript/TypeScript, Python, C/C++, C#, Go等
- 将代码视为数据,可以进行复杂的语义分析
- 内置大量安全规则
- 可扩展自定义查询
2. SSRF漏洞概述
服务器端请求伪造(SSRF)是一种安全漏洞,攻击者诱使服务器向内部系统发起非预期的请求。典型危害:
- 访问内部服务
- 绕过访问控制
- 扫描内部网络
- 攻击内部脆弱服务
3. CodeQL中的SSRF检测规则
3.1 基本检测原理
CodeQL检测SSRF主要通过以下模式:
- 识别用户可控的输入源(Source)
- 跟踪数据流到网络请求的发起点(Sink)
- 验证是否存在适当的防护措施
3.2 Java中的SSRF检测
关键类和方法
java.net.URL类及其openConnection()方法java.net.HttpURLConnection类java.net.URI类org.apache.http.client.HttpClient及相关方法
查询示例
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.SSRF
from SSRFRequest ssrf
select ssrf, "This HTTP request is potentially vulnerable to SSRF."
3.3 Python中的SSRF检测
关键模块和函数
urllib.request.urlopen()requests.get(),requests.post()httpx.get(),httpx.post()aiohttp.ClientSession().get()
查询示例
import python
import semmle.python.security.SSRF
from SSRFRequest ssrf
select ssrf, "Potential SSRF vulnerability in Python code."
4. 高级SSRF检测技术
4.1 数据流分析
CodeQL的强大之处在于可以跟踪复杂的数据流:
import java
import semmle.code.java.dataflow.DataFlow
from DataFlow::Node source, DataFlow::Node sink
where DataFlow::localFlow(source, sink)
select source, sink
4.2 污点跟踪
识别用户输入如何影响网络请求:
import java
import semmle.code.java.dataflow.TaintTracking
from TaintTracking::Configuration config, DataFlow::Node source, DataFlow::Node sink
where config.hasFlow(source, sink)
select source, sink, "User input flows to network request"
4.3 识别防护措施
检测是否存在SSRF防护:
import java
import semmle.code.java.security.SSRF
from SSRFRequest ssrf
where not ssrf.hasProtection()
select ssrf, "Unprotected SSRF vulnerability"
5. 实战案例
5.1 案例1:简单的Java SSRF
String url = request.getParameter("url");
URL u = new URL(url);
URLConnection conn = u.openConnection();
CodeQL会标记这种直接使用用户输入发起请求的模式。
5.2 案例2:间接SSRF
String apiEndpoint = "http://internal/api/" + userInput;
HttpClient.newBuilder().build().send(
HttpRequest.newBuilder().uri(URI.create(apiEndpoint)).build(),
HttpResponse.BodyHandlers.ofString());
CodeQL能跟踪字符串拼接后的数据流。
5.3 案例3:绕过防护的SSRF
String url = sanitizeUrl(request.getParameter("url"));
if(url.startsWith("http://example.com")) {
HttpClient.newHttpClient().send(
HttpRequest.newBuilder().uri(URI.create(url)).build(),
HttpResponse.BodyHandlers.ofString());
}
CodeQL可以检测不充分的URL验证。
6. 防护建议
在CodeQL查询中可以验证的防护措施:
- 白名单验证
- 禁用协议(如file://, gopher://)
- 使用内部DNS解析
- 网络层限制(如防火墙规则)
7. 自定义SSRF查询开发
7.1 定义Source
override predicate isSource(DataFlow::Node source) {
source.asParameter() = any(Request::getParameter).getAnUntrustedParameter()
or
source.asExpr() = any(RemoteFlowSource::remoteUserInput)
}
7.2 定义Sink
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod().hasName("openConnection") and
ma.getMethod().getDeclaringType().hasQualifiedName("java.net", "URL") and
sink.asExpr() = ma
)
}
7.3 完整查询示例
/**
* @name SSRF via URL.openConnection()
* @description Detects when user input flows into URL.openConnection()
* @kind path-problem
* @problem.severity warning
* @id java/ssrf-url-connection
*/
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import DataFlow::PathGraph
class SSRFConfig extends TaintTracking::Configuration {
SSRFConfig() { this = "SSRFConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod().hasName("openConnection") and
ma.getMethod().getDeclaringType().hasQualifiedName("java.net", "URL") and
sink.asExpr() = ma
)
}
}
from SSRFConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Potential SSRF vulnerability"
8. 优化查询技巧
- 提高精度:添加更多限制条件减少误报
- 提高召回率:扩大source和sink定义
- 性能优化:限制分析范围,使用更精确的数据流步骤
- 结果排序:按风险程度排序结果
9. 集成到CI/CD
将CodeQL SSRF检测集成到开发流程:
- 在PR时自动运行扫描
- 设置质量门限
- 与漏洞管理系统集成
- 定期更新查询规则库
10. 资源与进阶
- 官方文档:https://codeql.github.com/docs/
- GitHub高级安全:https://docs.github.com/en/code-security
- CodeQL标准库:https://github.com/github/codeql
- 社区查询:https://github.com/github/codeql/tree/main/java/ql/src/Security
通过系统学习和实践CodeQL的SSRF检测技术,可以显著提高代码审计效率,在开发早期发现潜在的安全风险。