URL跳转漏洞-原理到实战

admin 2025年6月18日23:32:58评论7 views字数 4434阅读14分46秒阅读模式
1. 定义

URL跳转漏洞(开放重定向漏洞)发生在Web应用程序未经验证地将用户重定向到第三方URL时。该漏洞允许攻击者构造恶意链接,将用户从可信网站重定向到钓鱼网站或恶意内容页面。

核心问题:应用程序将用户控制的输入直接用于重定向操作,未进行安全验证:

2. 现象

典型漏洞表现:


# 包含重定向参数的可疑URL
https://trusted-site.com/login?redirect=https://evil-phishing.com

http://bank.com/oauth?return_url=ftp://attacker.net

https://app.com/share?url=javascript:alert(document.cookie)

漏洞特征:

  • URL中包含redirectreturnurl等参数
  • 302状态码或HTML meta刷新跳转
  • 跳转后地址与当前域名不相关
  • 出现异常协议(如data:ftp:)或伪协议

3. 漏洞危害

风险类型 具体危害 案例说明
钓鱼攻击 窃取凭证/财务信息 伪造银行登录页窃取账号密码
恶意软件分发 诱导下载木马/勒索软件 "系统更新"提示下载带毒程序
信任欺骗 利用可信域名背书 https://company.com -> https://company-com.fake/login
绕过检测 规避安全防护机制 通过可信站点中转恶意链接
存储型XSS 配合脚本注入攻击 redirectUrl=data:text/html,alert(1)

4. 黑盒渗透测试方法

4.1 基础探测


GET /login?redirect=http://evil.com HTTP/1.1
Host: target.com

4.2 测试Payload清单

测试类型 测试Payload
外部域名 ?url=https://attacker.com
特殊协议 ?forward=ftp://evil.net
JS伪协议 ?target=javascript:alert(document.domain)
编码绕过 ?jump=https%3A%2F%2Fattacker.com
双重编码 ?return=%252F%252Fevil.com
IP地址 ?to=http://192.168.1.1
目录穿越 ?next=/../../../../etc/passwd
空字节注入 ?url=https://trusted.com.evil.com

4.3 Burp Suite自动化


# 使用Burp Intruder测试参数
1. 设置参数位置:`redirect=`[插入点]
2. 导入Payload列表:
   http://attacker.com
   javascript:alert(1)
   data:text/html,<script>malicious</script>
   /../../etc/passwd
3. 检查响应中的`Location`头

5. Java白盒审计指南

5.1 审计流程

URL跳转漏洞-原理到实战

5.2 关键审计点

  1. 定位危险方法


    // 正则搜索模式
    (sendRedirect|setHeader\(\"Location\")|ModelAndView\(\"redirect:)
  2. 回溯数据流


    // 示例:Spring MVC控制器
    @GetMapping("/redirect")
    public String redirect(@RequestParam String path) {
        // 跟踪path参数来源
        return "redirect:" + path; 
    }
  3. 验证防护逻辑

    • 白名单域名检查
    • 协议限制(仅允许http/https)
    • URL规范化处理
    • 路径合法性验证

6. Java中的关键代码

6.1 危险重定向方法

方法类型 危险代码示例
Servlet API response.sendRedirect(untrustedUrl);
Location Header response.setHeader("Location", inputUrl);
Spring Redirect return "redirect:" + request.getParam("url");
ModelAndView new ModelAndView("redirect:" + target);
RedirectView new RedirectView(userControlledUrl);

6.2 安全重定向示例


// 基于白名单的安全重定向
public void safeRedirect(HttpServletResponse response, String input) {
    final Set<String> ALLOWED_DOMAINS = Set.of("trusted.com", "partner.net");
    
    try {
        URI uri = new URI(input);
        // 验证协议
        if(!List.of("http", "https").contains(uri.getScheme())) {
            response.sendError(400, "Invalid scheme");
            return;
        }
        // 验证域名
        if(!ALLOWED_DOMAINS.contains(uri.getHost())) {
            response.sendRedirect("/default");
            return;
        }
        // 执行安全的重定向
        response.sendRedirect(uri.toString());
    } catch (URISyntaxException e) {
        response.sendError(400, "Invalid URL");
    }
}

7. PHP中的关键代码

危险重定向函数:


<?php
// 高危重定向函数
header("Location: " . $_GET['url']);
// 不安全的重定向方式
$url = $_POST['redirect'];
echo "<meta http-equiv='refresh' content='0;url=$url'>";
// 危险的重定向实现
die(header("Location: http://" . $_SERVER['HTTP_HOST'] . "/" . $_REQUEST['page']));

安全重定向实现:


<?php
$validRedirects = [
    '/dashboard' => true,
    '/profile' => true,
    '/settings' => true
];
$target = $_GET['target'] ?? '/default';
// 白名单验证
if(isset($validRedirects[$target])) {
    header("Location: $target");
} else {
    header("Location: /invalid");
}

8. Java漏洞代码

漏洞特征代码:


// 模式1:直接使用用户输入
public void unsafeRedirect1(HttpServletRequest request, HttpServletResponse response) {
    String target = request.getParameter("url");
    response.sendRedirect(target); // 高危!
}
// 模式2:路径拼接漏洞
public ModelAndView unsafeRedirect2(String section) {
    return new ModelAndView("redirect:/user/" + section); 
    // 若section="../../admin" 会导致路径穿越
}
// 模式3:未验证的Spring重定向
@GetMapping("/oauth/callback")
public String callback(@RequestParam String redirect_uri, String code) {
    return "redirect:" + redirect_uri + "?code=" + code; 
    // OAuth授权码泄露风险
}
// 模式4:协议控制漏洞
public void protocolRedirect(String url) {
    if(url.startsWith("http")) { // 仅检查前缀不安全
        response.sendRedirect(url); 
        // 允许http://attacker.com或http://localhost:[email protected]
    }
}

漏洞修复要点:

  1. 白名单校验:建立可跳转域名/路径白名单
  2. 协议过滤:仅允许http/https协议
  3. URL规范化:使用URI类解析标准化URL
  4. 域名验证:验证目标域名是否在可信列表
  5. 相对路径处理:禁止以../开头的相对路径

9.实战

redirect


// 满足参数url可控,且未做限制
public String vul(String url) {
    return "redirect:" + url;
}
       

  

没有任何限制,可以直接随意跳转


URL跳转漏洞-原理到实战

ModelAndView


// ModelAndView
public ModelAndView vul2(String url) {
    return new ModelAndView("redirect://" + url);
}
      

没有任何限制,同样随意跳转


URL跳转漏洞-原理到实战

response.sendRedirect


// response.sendRedirect
public void vul3(String url, HttpServletResponse response) throws IOException {
    response.sendRedirect(url);
}                 

没有任何限制,同样随意跳转

URL跳转漏洞-原理到实战

10.安全代码

白名单模式


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();
    System.out.println(host);
    
    return url_list.contains(host);
 }
不在范围内的均不能正确跳转
URL跳转漏洞-原理到实战

原文始发于微信公众号(今木安全):URL跳转漏洞-原理到实战

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月18日23:32:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   URL跳转漏洞-原理到实战https://cn-sec.com/archives/4178215.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息