Java代码审计之SSRF
字数 1249 2025-08-12 11:33:52

Java代码审计之SSRF漏洞详解

1. SSRF漏洞概述

SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。SSRF攻击的目标通常是从外网无法访问的内部系统。

关键特征

  • 由服务端发起请求
  • 能够访问与服务器相连的内部系统
  • 常出现在从其他服务器获取数据的功能中

2. SSRF漏洞原理

SSRF形成的主要原因:

  • 服务端提供了从其他服务器应用获取数据的功能
  • 没有对目标地址做充分的过滤与限制
  • 常见场景:获取网页文本内容、加载图片、下载文件等

本质:利用存在缺陷的web应用作为代理攻击远程和本地的服务器

3. Java中常见的网络请求协议

Java网络请求支持多种协议,包括:

  • file:/// - 本地文件系统
  • ftp:// - FTP协议
  • http:// - HTTP协议
  • https:// - HTTPS协议
  • jar:// - JAR文件
  • mailto:// - 邮件协议
  • netdoc:// - 网络文档

4. SSRF漏洞实例分析

4.1 URLConnection漏洞示例

漏洞代码

@GetMapping("/urlConnection/vuln")
public String URLConnectionVuln(String url) {
    return HttpUtils.URLConnection(url);
}

// HttpUtils.URLConnection方法
public static String URLConnection(String url) {
    try {
        URL u = new URL(url);
        URLConnection urlConnection = u.openConnection();
        BufferedReader in = new BufferedReader(
            new InputStreamReader(urlConnection.getInputStream()));
        
        String inputLine;
        StringBuilder html = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            html.append(inputLine);
        }
        in.close();
        return html.toString();
    } catch (Exception e) {
        logger.error(e.getMessage());
        return e.getMessage();
    }
}

攻击方式

http://localhost:8080/ssrf/urlConnection/vuln?url=file:///c:/windows/win.ini

漏洞点分析

  1. 直接使用用户提供的URL构造URL对象
  2. 调用openConnection()方法发起请求
  3. 无任何协议限制或过滤
  4. 可以读取本地文件(file:///协议)或访问内部网络资源

4.2 openStream漏洞示例

漏洞代码

URL u = new URL(url);
inputStream = u.openStream();

攻击方式

http://localhost:8080/ssrf/openStream?url=file:///c:/windows/win.ini

漏洞点分析

  1. openStream()方法内部调用了openConnection().getInputStream()
  2. 同样会根据传入的协议进行处理
  3. 可以用于探测内网或文件下载

5. SSRF防御方案

5.1 基础防御方案

协议白名单

public static boolean isHttp(String url) {
    return url.startsWith("http://") || url.startsWith("https://");
}

@GetMapping("/urlConnection/sec")
public String URLConnectionSec(String url) {
    // 拒绝非http/https协议
    if (!SecurityUtil.isHttp(url)) {
        return "[-] SSRF check failed";
    }
    // ...
}

局限性

  • 仅限制协议不足以防止对内网的探测
  • 攻击者仍可能使用http://127.0.0.1http://内网IP进行攻击

5.2 高级防御方案

Hook机制

@GetMapping("/urlConnection/sec")
public String URLConnectionSec(String url) {
    // 拒绝非http/https协议
    if (!SecurityUtil.isHttp(url)) {
        return "[-] SSRF check failed";
    }
    try {
        SecurityUtil.startSSRFHook();  // 开启SSRF Hook
        return HttpUtils.URLConnection(url);
    } catch (SSRFException | IOException e) {
        return e.getMessage();
    } finally {
        SecurityUtil.stopSSRFHook();  // 关闭SSRF Hook
    }
}

Hook机制优势

  • 可以监控和限制网络请求行为
  • 防止对内网资源的访问
  • 提供更细粒度的控制

6. 完整防御建议

  1. 协议限制:只允许http/https协议
  2. 域名/IP白名单:限制可访问的域名或IP范围
  3. 禁用重定向:防止通过重定向访问内部资源
  4. URL解析:严格解析URL,防止使用特殊字符绕过
  5. 请求内容检查:检查返回内容是否符合预期
  6. 网络层限制:服务器网络配置限制对内部系统的访问
  7. 认证机制:对内部服务启用认证

7. 关键Java API风险点

需要特别注意的Java API:

  • URL.openConnection()
  • URL.openStream()
  • HttpClient.execute()
  • HttpURLConnection.connect()
  • Request.Get/Post.execute()

这些API都可能成为SSRF漏洞的入口点,使用时必须进行严格的输入验证和过滤。

Java代码审计之SSRF漏洞详解 1. SSRF漏洞概述 SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。SSRF攻击的目标通常是从外网无法访问的内部系统。 关键特征 : 由服务端发起请求 能够访问与服务器相连的内部系统 常出现在从其他服务器获取数据的功能中 2. SSRF漏洞原理 SSRF形成的主要原因: 服务端提供了从其他服务器应用获取数据的功能 没有对目标地址做充分的过滤与限制 常见场景:获取网页文本内容、加载图片、下载文件等 本质 :利用存在缺陷的web应用作为代理攻击远程和本地的服务器 3. Java中常见的网络请求协议 Java网络请求支持多种协议,包括: file:/// - 本地文件系统 ftp:// - FTP协议 http:// - HTTP协议 https:// - HTTPS协议 jar:// - JAR文件 mailto:// - 邮件协议 netdoc:// - 网络文档 4. SSRF漏洞实例分析 4.1 URLConnection漏洞示例 漏洞代码 : 攻击方式 : 漏洞点分析 : 直接使用用户提供的URL构造URL对象 调用 openConnection() 方法发起请求 无任何协议限制或过滤 可以读取本地文件( file:/// 协议)或访问内部网络资源 4.2 openStream漏洞示例 漏洞代码 : 攻击方式 : 漏洞点分析 : openStream() 方法内部调用了 openConnection().getInputStream() 同样会根据传入的协议进行处理 可以用于探测内网或文件下载 5. SSRF防御方案 5.1 基础防御方案 协议白名单 : 局限性 : 仅限制协议不足以防止对内网的探测 攻击者仍可能使用 http://127.0.0.1 或 http://内网IP 进行攻击 5.2 高级防御方案 Hook机制 : Hook机制优势 : 可以监控和限制网络请求行为 防止对内网资源的访问 提供更细粒度的控制 6. 完整防御建议 协议限制 :只允许http/https协议 域名/IP白名单 :限制可访问的域名或IP范围 禁用重定向 :防止通过重定向访问内部资源 URL解析 :严格解析URL,防止使用特殊字符绕过 请求内容检查 :检查返回内容是否符合预期 网络层限制 :服务器网络配置限制对内部系统的访问 认证机制 :对内部服务启用认证 7. 关键Java API风险点 需要特别注意的Java API: URL.openConnection() URL.openStream() HttpClient.execute() HttpURLConnection.connect() Request.Get/Post.execute() 这些API都可能成为SSRF漏洞的入口点,使用时必须进行严格的输入验证和过滤。