JAVA代码审计-url跳转漏洞原理与案例
字数 1671 2025-08-10 19:49:11

Java代码审计:URL跳转漏洞原理与防御指南

一、URL跳转漏洞概述

URL跳转漏洞(也称为URL重定向漏洞)是由于服务端未对传入的跳转地址进行检查和控制,导致攻击者可以构造任意恶意地址,诱导用户跳转至恶意站点。这种漏洞常用于钓鱼攻击,利用用户对可信站点的信任进行欺骗。

漏洞危害

  1. 钓鱼攻击:诱导用户输入敏感信息
  2. 绕过安全机制:绕过基于白名单的安全校验
  3. 内网探测:支持其他协议时可能导致内网信息泄露
  4. 信任链破坏:从可信站点跳转增加用户信任度

二、漏洞常见触发点

1. 常见触发函数

redirect, redirectUrl, callback, return_url, toUrl, ReturnUrl, 
fromUrl, redUrl, request, redirect_to, redirect_url, jump, 
jump_to, target, to, goto, link, linkto, domain

2. 常见业务场景

  • 登录认证后的跳转
  • 用户分享/收藏内容后的跳转
  • 跨站点认证/授权后的跳转
  • 站内链接点击跳转
  • 用户交互页面跳转(如评价、问卷等)
  • 业务完成后的跳转(如修改密码后跳转登录页)

三、漏洞代码示例与分析

1. Spring MVC重定向漏洞

漏洞代码1:直接重定向

@GetMapping("/redirect")
public String redirect(@RequestParam("url") String url) {
    return "redirect:" + url;
}

问题:直接拼接用户输入的url参数,未做任何校验

漏洞代码2:setHeader重定向

@RequestMapping("/setHeader")
public static void setHeader(HttpServletRequest request, HttpServletResponse response) {
    String url = request.getParameter("url");
    response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // 301
    response.setHeader("Location", url);
}

漏洞代码3:sendRedirect重定向

@RequestMapping("/sendRedirect")
public static void sendRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String url = request.getParameter("url");
    response.sendRedirect(url); // 302
}

2. ModelAndView重定向漏洞

@RequestMapping("/redirect1")
public ModelAndView ModelAndView(HttpServletRequest request, HttpServletResponse response){
    String url = request.getParameter("url");
    url = "redirect:" + url;
    return new ModelAndView(url);
}

3. RedirectAttributes重定向

@RequestMapping("/redirect4")
public String RedirectAttributes(RedirectAttributes redirectAttributes, String url){
    redirectAttributes.addAttribute("id", url);
    return "redirect:/index";
}

四、安全防护方案

1. 使用RequestDispatcher转发(安全)

@RequestMapping("/forward")
public static void forward(HttpServletRequest request, HttpServletResponse response) {
    String url = request.getParameter("url");
    RequestDispatcher rd = request.getRequestDispatcher(url);
    try {
        rd.forward(request, response);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

优点:只能跳转同一web应用内的路径,不会改变浏览器地址栏URL

2. 白名单校验

@RequestMapping("/sendRedirect/sec")
public void sendRedirect_seccode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String url = request.getParameter("url");
    if (SecurityUtil.checkURL(url) == null) {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.getWriter().write("url forbidden");
        return;
    }
    response.sendRedirect(url);
}

public static boolean isWhite(String url) {
    List<String> url_list = new ArrayList<String>();
    url_list.add("baidu.com");
    url_list.add("www.baidu.com");
    url_list.add("oa.baidu.com");
    
    URI uri = null;
    try {
        uri = new URI(url);
    } catch (URISyntaxException e) {
        System.out.print(e);
    }
    String host = uri.getHost().toLowerCase();
    return url_list.contains(host);
}

3. 其他防护措施

  • 固定跳转目标URL(不可控)
  • 给用户展示安全风险提示,由用户确认跳转
  • 记录跳转日志用于审计

五、漏洞利用与绕过技术

1. 直接跳转

https://victim.com/redirect?url=http://evil.com

2. 协议一致性绕过

https://victim.com/redirect?url=https://evil.com

3. 域名字符串检测欺骗

https://victim.com/redirect?url=http://evil.com/victim.com

4. 可信站多次重定向

https://victim.com/redirect?url=https://trusted.com/redirect?url=evil.com

5. 特殊字符绕过技术

10种常见绕过方式:

  1. 单斜线"/"绕过:/www.evil.com
  2. 缺少协议绕过://www.evil.com
  3. 多斜线"/"前缀绕过:///www.evil.com
  4. "@"符号绕过:https://victim.com@www.evil.com
  5. 反斜线""绕过:https://www.evil.com\www.victim.com
  6. "#"符号绕过:https://www.evil.com#www.victim.com
  7. "?"号绕过:https://www.evil.com?www.victim.com
  8. 双反斜线绕过:https://www.evil.com\\www.victim.com
  9. "."字符绕过:.evil.com(跳转到evil.com)
  10. 重复特殊字符:////www.evil.com//..

6. 其他绕过思路

  • 跳转到IP地址而非域名
  • 使用IPv6地址
  • IP地址的十进制/八进制/十六进制表示
  • 更换协议(ftp、gopher等)
  • 借鉴SSRF绕过技巧

六、审计方法与防御建议

1. 审计关键点

  • 查找所有重定向相关函数调用
  • 检查重定向目标是否用户可控
  • 验证是否存在白名单校验
  • 检查校验逻辑是否可绕过

2. 防御建议

  1. 使用白名单校验重定向目标
  2. 固定跳转目标URL(不可控)
  3. 使用RequestDispatcher进行服务端跳转
  4. 对用户展示跳转风险提示
  5. 记录所有跳转操作日志
  6. 定期进行安全审计和渗透测试

七、实际案例分析

案例1:eyoucms任意URL跳转

漏洞点:logout()函数中referurl参数未校验

$referurl = input('referurl');
redirect($referurl);

利用:构造恶意referurl参数实现任意跳转

案例2:开放端口导致的URL跳转

漏洞点:开放端口接收特定数据可导致访问任意URL

案例3:Spring MVC视图操纵

漏洞点:模板路径拼接用户输入

@GetMapping("/path")
public String path(@RequestParam String lang) {
    return "user/" + lang + "/welcome"; // 模板路径污染
}

POC:使用Thymeleaf SSTI payload

__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22calc.exe%22).getInputStream()).next()%7d__::.x

八、总结

URL跳转漏洞虽然看似简单,但危害严重且利用方式多样。开发人员应:

  1. 避免直接使用用户输入作为跳转目标
  2. 实施严格的白名单校验机制
  3. 考虑使用服务端跳转替代客户端重定向
  4. 对用户进行风险提示
  5. 定期进行安全审计

安全人员在进行代码审计时应重点关注所有重定向相关函数,验证目标URL的校验逻辑是否完备,是否存在绕过可能。

Java代码审计:URL跳转漏洞原理与防御指南 一、URL跳转漏洞概述 URL跳转漏洞(也称为URL重定向漏洞)是由于服务端未对传入的跳转地址进行检查和控制,导致攻击者可以构造任意恶意地址,诱导用户跳转至恶意站点。这种漏洞常用于钓鱼攻击,利用用户对可信站点的信任进行欺骗。 漏洞危害 钓鱼攻击:诱导用户输入敏感信息 绕过安全机制:绕过基于白名单的安全校验 内网探测:支持其他协议时可能导致内网信息泄露 信任链破坏:从可信站点跳转增加用户信任度 二、漏洞常见触发点 1. 常见触发函数 2. 常见业务场景 登录认证后的跳转 用户分享/收藏内容后的跳转 跨站点认证/授权后的跳转 站内链接点击跳转 用户交互页面跳转(如评价、问卷等) 业务完成后的跳转(如修改密码后跳转登录页) 三、漏洞代码示例与分析 1. Spring MVC重定向漏洞 漏洞代码1:直接重定向 问题 :直接拼接用户输入的url参数,未做任何校验 漏洞代码2:setHeader重定向 漏洞代码3:sendRedirect重定向 2. ModelAndView重定向漏洞 3. RedirectAttributes重定向 四、安全防护方案 1. 使用RequestDispatcher转发(安全) 优点 :只能跳转同一web应用内的路径,不会改变浏览器地址栏URL 2. 白名单校验 3. 其他防护措施 固定跳转目标URL(不可控) 给用户展示安全风险提示,由用户确认跳转 记录跳转日志用于审计 五、漏洞利用与绕过技术 1. 直接跳转 2. 协议一致性绕过 3. 域名字符串检测欺骗 4. 可信站多次重定向 5. 特殊字符绕过技术 10种常见绕过方式: 单斜线"/"绕过: /www.evil.com 缺少协议绕过: //www.evil.com 多斜线"/"前缀绕过: ///www.evil.com "@"符号绕过: https://victim.com@www.evil.com 反斜线"\"绕过: https://www.evil.com\www.victim.com "#"符号绕过: https://www.evil.com#www.victim.com "?"号绕过: https://www.evil.com?www.victim.com 双反斜线绕过: https://www.evil.com\\www.victim.com "."字符绕过: .evil.com (跳转到evil.com) 重复特殊字符: ////www.evil.com//.. 6. 其他绕过思路 跳转到IP地址而非域名 使用IPv6地址 IP地址的十进制/八进制/十六进制表示 更换协议(ftp、gopher等) 借鉴SSRF绕过技巧 六、审计方法与防御建议 1. 审计关键点 查找所有重定向相关函数调用 检查重定向目标是否用户可控 验证是否存在白名单校验 检查校验逻辑是否可绕过 2. 防御建议 使用白名单校验重定向目标 固定跳转目标URL(不可控) 使用RequestDispatcher进行服务端跳转 对用户展示跳转风险提示 记录所有跳转操作日志 定期进行安全审计和渗透测试 七、实际案例分析 案例1:eyoucms任意URL跳转 漏洞点 :logout()函数中referurl参数未校验 利用 :构造恶意referurl参数实现任意跳转 案例2:开放端口导致的URL跳转 漏洞点 :开放端口接收特定数据可导致访问任意URL 案例3:Spring MVC视图操纵 漏洞点 :模板路径拼接用户输入 POC :使用Thymeleaf SSTI payload 八、总结 URL跳转漏洞虽然看似简单,但危害严重且利用方式多样。开发人员应: 避免直接使用用户输入作为跳转目标 实施严格的白名单校验机制 考虑使用服务端跳转替代客户端重定向 对用户进行风险提示 定期进行安全审计 安全人员在进行代码审计时应重点关注所有重定向相关函数,验证目标URL的校验逻辑是否完备,是否存在绕过可能。