url动态加解密

个人博客原文地址:url动态加解密 | DevotedWife's Yard.

表单提交(或其他需要请求后台url)的场景下,url对于客户端来说是可见的,攻击者可以通过url猜测到很多信息并伪造请求对url进行攻击。本文探讨了一种对
url加密和解密的方案,并给出了关键代码。

Form表单提交

  1. 页面form的action地址加密:

    先在原始url之前添加encoded/(或其他)以方便后台认证是否合法url;
    在加密后的url地址后加.do(或其他)以方便filter过滤。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <%
        String url = DesUtil.encrypt("encoded/test/second.htm");
    %>
    <form action="<%=url%>.do" method="post">
        <input type="text" id="account" name="j_username" class="text " placeholder="请输入手机号/邮箱"
               value="tangliu"/>
        <input type="text" id="password" name="j_password" class="text " placeholder="请输入密码"
               value="123456"/>
        <input type="submit" value="Submit" />
    </form>
    
  2. 自定义一个filter,放在其他filter之前:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <filter>
        <filter-name>decodeFilter</filter-name>
        <filter-class>com.tangliu.test.encodeurl.DecodeUrlFilter</filter-class>
        <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
        <filter-name>decodeFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    
  3. filter中对url进行解密,若解密后的url不符合规范(不是以”encoded/“开头),则抛弃,否则对url请求进行forward转发。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        try {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String encodedUrl = httpRequest.getRequestURI();
            encodedUrl = encodedUrl.substring(1, (encodedUrl.length() - 3));
    
            String unencodedUrl = DesUtil.decrypt(encodedUrl);
            //如果解密后不是以encoded开头则说明不是合法请求,抛弃
            if(!unencodedUrl.startsWith("encoded"))
                return;
    
            unencodedUrl = unencodedUrl.replace("encoded/", "");
            unencodedUrl = httpRequest.getContextPath() + unencodedUrl;
            request.getRequestDispatcher("/" + unencodedUrl).forward(request, response);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
  4. 经过测试,froward转发的url可以被其他filter正确拦截,于此同时地址栏显示的是加密后的url,设置如下:

 
1
2
3
4
5
6
7
8
9
10
11
 <filter>
    <filter-name>testFilter</filter-name>
    <filter-class>com.tangliu.test.encodeurl.TestFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>testFilter</filter-name>
    <url-pattern>/test/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

其中`<dispatcher>`标签如果不设置,默认是REQUEST,表示拦截客户端请求,`FORWARD`表示拦截内部的forward请求。

  1. 同时最后收到请求的controller,能够正常接收request的参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @RequestMapping(value = "second", method = RequestMethod.POST)
    @ResponseBody
    public String service(HttpServletRequest request) {
    
        System.out.println(request.getParameter("j_username"));
        System.out.println(request.getParameter("j_password"));
    
        return "test";
    }
    

使用ajax post提交

  1. <meta>中写入加密后的url地址:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    <meta name="formUrl" content="<%=DesUtil.encrypt("encoded/test/second.htm")%>.do">
    <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
    <script>
        function ajaxTest(){
    
            var url = $("meta[name='formUrl']").attr("content");
            var data = {};
            data['j_username'] = 'tangliu';
            data['j_password'] = '123456';
            $.post(url, data, function(result){
                alert(result);
            });
    
        }
    </script>
    
  2. <script>中写入加密后的url地址:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    <script>
        function ajaxTest(){
    
            var url = "<%=DesUtil.encrypt("encoded/test/second.htm")%>.do";
            var data = {};
            data['j_username'] = 'tangliu';
            data['j_password'] = '123456';
            $.post(url, data, function(result){
                alert(result);
            });
        }
    </script>
    

测试可行。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值