目录
  • url跳转常见的地方
  • url跳转常用到的参数
    • 核心代码:
  • 修复方式:

    URLRedirect url重定向漏洞也称url任意跳转漏洞,网站信任了用户的输入导致恶意攻击,url重定向主要用来钓鱼,比如url跳转中最常见的跳转在登陆口,支付口,也就是一旦登陆将会跳转任意自己构造的网站,如果设置成自己的url则会造成钓鱼。

    url跳转常见的地方

    1. 登陆跳转我认为是最常见的跳转类型,认证完后会跳转,所以在登陆的时候建议多观察url参数
    2. 用户分享、收藏内容过后,会跳转
    3. 跨站点认证、授权后,会跳转
    4. 站内点击其它网址链接时,会跳转
    5. 在一些用户交互页面也会出现跳转,如请填写对客服评价,评价成功跳转主页,填写问卷,等等业务,注意观察url。
    6. 业务完成后跳转这可以归结为一类跳转,比如修改密码,修改完成后跳转登陆页面,绑定银行卡,绑定成功后返回银行卡充值等页面,或者说给定一个链接办理VIP,但是你需要认证身份才能访问这个业务,这个时候通常会给定一个链接,认证之后跳转到刚刚要办理VIP的页面。

    url跳转常用到的参数

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

    核心代码:

    重定向跳转(ViewResolver):

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

    301跳转:

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

    302跳转:

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

    修复方式:

    转发(前往),服务器内部的重定向,在Servlet中通过RequestDispatcher转发给另一个程序处理请求,请求的数据依然在。所以forward相当于客户端向服务器发送一次请求,服务器处理两次,请求数据不会消失且URL地址只变化一次。
    只能内部跳转

    @RequestMapping("/forward")
    @ResponseBody
    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();
        }
    }

    通过checkURL去检查输入的参数

    @RequestMapping("/sendRedirect/sec")
        @ResponseBody
        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);
        }
    }

    跟进

    /**
     * 同时支持一级域名和多级域名,相关配置在resources目录下url/url_safe_domain.xml文件。
     * 优先判断黑名单,如果满足黑名单return null。
     *
     * @param url the url need to check
     * @return Safe url returns original url; Illegal url returns null;
     */
    public static String checkURL(String url) {
    ​
        if (null == url){
            return null;
        }
    ​
        ArrayList<String> safeDomains = WebConfig.getSafeDomains();
        ArrayList<String> blockDomains = WebConfig.getBlockDomains();
    ​
        try {
            String host = gethost(url);
    ​
            // 必须http/https
            if (!isHttp(url)) {
                return null;
            }
    ​
            // 如果满足黑名单返回null
            if (blockDomains.contains(host)){
                return null;
            }
            for(String blockDomain: blockDomains) {
                if(host.endsWith("." + blockDomain)) {
                    return null;
                }
            }
    ​
            // 支持多级域名
            if (safeDomains.contains(host)){
                return url;
            }
    ​
            // 支持一级域名
            for(String safedomain: safeDomains) {
                if(host.endsWith("." + safedomain)) {
                    return url;
                }
            }
            return null;
        } catch (NullPointerException e) {
            logger.error(e.toString());
            return null;
        }
    }

    检测相关url是否在自己配置中,若不在则返回NULL

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。