欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

需要处理 ##正确地处理URL 感觉这个有必要再次说 昆山软件开发 明下: http://docs.oracle.com

点击: 次  来源:宝鼎软件 时间:2017-05-31

原文出处: hengyunabc

缘起

首先,用查抄Referer的方法来防披御CSRF并不是很好的要领。因项目姑且有需要,所以做为过渡方案。
为什么判定referer不是很好的步伐?

  • referer 大概为空
  • https跳转http没有referer
    https跳转差异的域名的https没有referer
    通过非凡结构的POST请求没有referer
    一些的proxy会把referer去掉
    用户直接在欣赏器里会见(GET请求)

  • 判定的逻辑巨大(用正则匹配?)
  • 友站中招,殃及池鱼
  • 可以作为过渡方案,非持久之计
  • 结构空referer请求的一些参考资料

  • Stripping Referrer for fun and profit
  • Stripping the Referer in a Cross Domain POST request
  • 防止CSRF今朝较量好的步伐是CSRF Token,参考另一篇blog:Cookie & Session & CSRF。

    ##收集资料

    先搜索下前人有没有这类相关的事情。
    搜索到的关于RefererFilter的信息并不多。

    不外这里学到了一些东东:

    https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.security-1.0.0/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
  • 是否答允localhost, 127.0.0.1这样referer的请求?
  • 是否答允当地的IP/host的请求?
  • 再搜索下java里提取request的referer的要领,尚有filter里重定向请求的要领。
    再仔细看了下OWASP的文档:

    https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

    ##确定方案

  • 默认拦截“POST|PUT|DELETE|CONNECT|PATCH”的请求
  • HttpServletRequest里提取到referer
  • 用java.net.URL来提取referer里的host
  • 判定host是否切合要求,支持完全匹配的域名和子域名
  • 不切合要求的请求回应403可能重定向到指定的页面
  • 为什么不消正则的方法来处理惩罚referer?

  • 正则表达式凡是较量慢
  • 很难判定一个巨大的正则表达式是否真的正确
  • URL是很巨大的,不要手动处理惩罚URL,参考URL的语法
  • ##思考需要提供的设置项

    实际最终提供了这些设置项,思量到像host这样的设置不是常常变换的,所以没有提供从外部设置文件加载设置的成果。

    matchMethods   即拦截的要领,默认值"POST|PUT|DELETE|CONNECT|PATCH",凡是不消设置
    allowSubDomainHosts 匹配子域名,以"|"脱离,如"test.com|abc.com",
                         则http://test.com, http://xxx.test.com这样的请求城市匹配到,推荐优先利用这个设置
    completeMatchHosts 完全匹配的域名,以"|"脱离,如"test.com|abc.com",则只有http://test.com 这样的请求会匹配
                        像http://www.test.com 这样的请求不会被匹配
    
    responseError  被拦截的请求的response的返回值,默认是403
    redirectPath   被拦截的请求重定向到的url,假如设置了这个值,则会忽略responseError的设置。
                        好比可以设置重定向到本身界说的错误页: /referer_error.html
    bAllowEmptyReferer  是否答允空referer,默认是false,除非很清楚,不然不要窜改这个
    bAllowLocalhost   是否答允localhost, 127.0.0.1 这样的referer的请求,默认是true,便于调试
    bAllowAllIPAndHost  是否答允本机的所有IP和host的referer请求,默认是false

    ##编码的细节

  • 重定向时,软件开发,留意加上contextPath
  • response.sendRedirect(request.getContextPath() + redirectPath);
  • 结构URL时,犯科的URL会抛出RuntimeException,需要处理惩罚
  • ##正确地处理惩罚URL

    感受这个有须要再次说明下:

    http://docs.oracle.com/javase/tutorial/networking/urls/urlInfo.html

    用contain, indexOf, endWitch这些函数时都要小心。

    public static void main(String[] args) throws Exception {
           URL aURL = new URL("http://example.com:80/docs/books/tutorial"
                              + "/index.html?name=networking#DOWNLOADING");
           System.out.println("protocol = " + aURL.getProtocol());
           System.out.println("authority = " + aURL.getAuthority());
           System.out.println("host = " + aURL.getHost());
           System.out.println("port = " + aURL.getPort());
           System.out.println("path = " + aURL.getPath());
           System.out.println("query = " + aURL.getQuery());
           System.out.println("filename = " + aURL.getFile());
           System.out.println("ref = " + aURL.getRef());
       }

    ##用curl来测试

    最后用curl来做了一些测试:

    curl  --header "Referer:http://test.com" http://localhost:8080/filter-test/referer
    curl -X POST --header "Referer:http://test.com" http://localhost:8080/filter-test/referer
    curl -X POST --header "Referer:xxxxx" http://localhost:8080/filter-test/referer
    curl -X POST http://localhost:8080/filter-test/referer
    curl -X POST --header "Referer:http://abc.test.com" http://localhost:8080/filter-test/referer
    curl -X POST --header "Referer:http://abc.hello.com.test.com" http://localhost:8080/filter-test/referer