Java代码审计中的SSRF漏洞深度解析
字数 1391 2025-08-29 08:30:12
Java代码审计中的SSRF漏洞深度解析
一、SSRF漏洞原理与危害
1.1 SSRF定义
SSRF(Server-Side Request Forgery)即服务端请求伪造漏洞,攻击者通过构造恶意请求使服务端发起非预期的网络请求。
1.2 主要危害
- 访问内部敏感系统(如数据库、管理后台)
- 端口扫描探测内网服务
- 通过文件协议(file://)读取本地文件
- 与其他漏洞形成链式攻击(如XXE+SSRF组合攻击)
二、Java中常见的SSRF漏洞场景
2.1 Spring MVC HttpURLConnection漏洞
漏洞代码示例
import org.springframework.web.bind.annotation.*;
import java.net.*;
import java.io.*;
@RestController
public class VulnerableController {
@GetMapping("/request")
public String requestUrl(@RequestParam("url") String urlString) throws IOException {
URL url = new URL(urlString); // 漏洞根源:直接使用未校验的用户输入
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// 读取响应内容
StringBuilder response = new StringBuilder();
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
}
return response.toString();
}
}
漏洞执行流程分析
- 攻击入口:攻击者访问
/request?url=http://attacker.com端点 - 参数注入:
urlString参数直接接收用户输入(如http://192.168.1.1:8080) - 建立连接:
new URL(urlString)未做任何校验即实例化URL对象 - 发起请求:
conn.getInputStream()触发网络请求 - 数据泄露:读取响应内容并返回给攻击者
典型利用场景
GET /request?url=file:///etc/passwd HTTP/1.1
GET /request?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1 # AWS元数据
2.2 Apache HttpClient漏洞
漏洞代码示例
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
@GetMapping("/apacheRequest")
public String apacheRequest(String url) throws Exception {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet request = new HttpGet(url); // 漏洞点:直接使用用户输入
try (CloseableHttpResponse response = client.execute(request)) {
return EntityUtils.toString(response.getEntity());
}
}
}
漏洞触发路径
- 请求构造:
HttpGet直接使用未过滤的URL参数 - 协议支持:默认支持
http/https/ftp/file等协议
攻击示例
// 探测Redis服务
client.execute(new HttpGet("http://127.0.0.1:6379"))
// 读取本地文件
client.execute(new HttpGet("file:///C:/Windows/win.ini"))
2.3 OkHttpClient漏洞
漏洞代码示例
import okhttp3.*;
@GetMapping("/okHttpRequest")
public String okHttpRequest(String inputUrl) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(inputUrl) // 漏洞核心:未校验的URL输入
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
漏洞利用特征
- 协议处理:支持
http/https/ftp/file/jar等协议 - 绕过技巧:
// 使用302跳转绕过白名单检测
.url("http://safe.com/redirect?target=http://internal")
三、SSRF漏洞防御方案
3.1 输入验证与过滤
- 白名单校验:只允许访问特定的域名或IP
- 协议限制:禁止
file://、ftp://等危险协议 - URL解析:使用
java.net.URI代替java.net.URL进行更严格的解析
3.2 网络层防护
- 内网访问限制:禁止访问私有IP段(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- DNS重绑定防护:验证DNS解析结果与请求目标是否一致
3.3 代码实现建议
- 使用安全的HTTP客户端:配置默认的协议限制
- 响应处理:不将原始响应直接返回给客户端
- 认证与授权:确保服务端请求也经过适当的认证
四、修复代码示例
4.1 Spring MVC安全实现
@GetMapping("/safeRequest")
public String safeRequest(@RequestParam("url") String urlString) throws IOException {
// 白名单校验
if (!urlString.startsWith("https://trusted.com/")) {
throw new IllegalArgumentException("Invalid URL");
}
// 使用URI进行更严格的解析
URI uri = new URI(urlString);
URL url = uri.toURL();
// 其他安全措施...
}
4.2 Apache HttpClient安全配置
@GetMapping("/safeApacheRequest")
public String safeApacheRequest(String url) throws Exception {
// 验证URL
if (!isUrlAllowed(url)) {
throw new SecurityException("URL not allowed");
}
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet request = new HttpGet(url);
// 设置超时防止SSRF导致的拒绝服务
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.build();
request.setConfig(config);
try (CloseableHttpResponse response = client.execute(request)) {
return sanitizeResponse(EntityUtils.toString(response.getEntity()));
}
}
}
五、高级攻击场景
5.1 云服务元数据利用
http://169.254.169.254/latest/meta-data/ # AWS
http://metadata.google.internal/computeMetadata/v1/ # GCP
http://100.100.100.200/latest/meta-data/ # Alibaba Cloud
5.2 组合攻击
- XXE+SSRF:通过XML外部实体注入触发SSRF
- SSRF+Redis:利用SSRF攻击内网Redis服务
- SSRF+CRLF:结合CRLF注入构造更复杂的攻击
六、审计要点总结
- 查找网络请求点:搜索
URL、HttpURLConnection、HttpClient等关键字 - 检查输入来源:确认URL参数是否来自用户可控输入
- 验证过滤逻辑:检查是否有完整的URL验证机制
- 测试协议支持:尝试
file://、ftp://等非HTTP协议 - 尝试绕过技巧:测试重定向、DNS重绑定等绕过方法
通过全面理解SSRF漏洞的原理、实现方式和防御措施,开发人员和安全审计人员可以更有效地识别和防范这类安全风险。