• 转-CSRF&OWASP CSRFGuard


    一. 什么是CSRF?
    CSRF(Cross-Site Request Forgery)直译的话就是跨站点请求伪造
    也就是说在用户会话下对某个需要验证的网络应用发送GET/POST请求——而这些请求是未经用户允许并且用户未必愿意做。

    举例先:
    用户小a是某论坛的管理员,刚刚用他的用户名、密码登录了该论坛。
    攻击者现在利用一些手段(例如通过email或聊天窗口发给小a一个链接),但小a点击该链接时,在小a不知情的情况下,攻击者可以将事先设定好的操作直接执行,例如将自己在该论坛的权限从普通变成管理员。

    更加具体的解释,请参见老K的笔记

    二. 怎么样防御?
    本文使用OWASP(The Open Web Application Security Project)下的CSRFGuard3来做防御。

    1. 下载最新的CSRFGuard相关的jar包跟配置文件;
    2. 将Owasp.CsrfGuard.jar拷贝到你的应用的classpath中(常见的就是拷贝到web程序的web-inf目录下);
    3. 注入Token (具体注入方式参见https://www.owasp.org/index.php/CSRFGuard_3_Token_Injection)
    Token的注入有两种方式,一种是JavaScript DOM,另一种是用提供的JSP Tag Library。两种方式并不冲突,OWASP建议两种并用。
    JS动态注入
           其实使用起来很简单,只需要简单的几个步骤:
          a. 将Owasp.CsrfGuard.js放到WEB-INF下面
          b. Map JavaScriptServlet       
          在web.xml中,加入如下

         <servlet>
           <servlet-name>JavaScriptServlet</servlet-name>
           <servlet-class>org.owasp.csrfguard.servlet.JavaScriptServlet</servlet-class>
           <init-param>
              <param-name>source-file</param-name>
              <param-value>WEB-INF/csrfguard.js</param-value>
           </init-param>
           <init-param>
              <param-name>inject-into-forms</param-name>
              <param-value>true</param-value>
           </init-param>
           <init-param>
              <param-name>inject-into-attributes</param-name>
              <param-value>true</param-value>
           </init-param>
           <init-param>
             <param-name>domain-strict</param-name>
             <param-value>false</param-value>
           </init-param>
           <init-param>
             <param-name>referer-pattern</param-name>
             <param-value>.*</param-value>
           </init-param>
        </servlet>

        <servlet-mapping>
           <servlet-name>JavaScriptServlet</servlet-name>
           <url-pattern>/JavaScriptServlet</url-pattern>
        </servlet-mapping>
       这一段的作用是给所有指定范围内的js调用进行保护。
    JSP Tag
          a. 配置web.xml,加入如下内容
     <context-param>
           <param-name>Owasp.CsrfGuard.Config</param-name>
           <param-value>WEB-INF/owasp.csrfguard.properties</param-value>
        </context-param>
        <context-param>
           <param-name>Owasp.CsrfGuard.Config.Print</param-name>
           <param-value>true</param-value>
        </context-param>
        <listener>
           <listener-class>org.owasp.csrfguard.CsrfGuardListener</listener-class>
        </listener>
        <filter>
        <filter-name>CSRFGuard</filter-name>
           <filter-class>org.owasp.csrfguard.CsrfGuardFilter</filter-class>
        </filter>
        <filter-mapping>
           <filter-name>CSRFGuard</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
      
    Owasp.CsrfGuard.Config参数定义了Owasp.CsrfGuard.properties的位置,该properties文件包含了csrfGuard可配置的参数
    Owasp.CsrfGuard.Config.Print参数是可选的,它只是用来记log的
    CsrfGuardListener为所有新创建的HttpSessions解析context参数并初始化CsrfGuard context
    CsrfGuardFilter处理传过来的request,并将mapping中指定需要保护的url转发到csrfguard处理
         b. 引入taglib 
         <%@ taglib uri="http://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project/Owasp.CsrfGuard.tld" prefix="csrf" %>
         c. 加入jsp tag
         在需要保护的URI的?号后,参数前面,加入
    <csrf:token/>
    例如, 我想保护test.jsp?parm1&parm2这段URI,防止CSRF,那么就改成
    test.jsp?<csrf:token uri="test.jsp"/>&parm1&parm2

    这里<csrf:token/>在实际运行时会被替换为生成的token值
    4. 配置Owasp.CsrfGuard.properties文件(详细请参见https://www.owasp.org/index.php/CSRFGuard_3_Configuration)
    最少需要配置如下参数  
    org.owasp.csrfguard.NewTokenLandingPage属性
    org.owasp.csrfguard.unprotected属性
    org.owasp.csrfguard.action.Redirect.Page属性
    三. 测试
    假如:
    首页:/csrfGuardTest/index.jsp
     <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project/Owasp.CsrfGuard.tld" prefix="csrf" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    <a href="http://localhost:8080/Owasp.CsrfGuard.Test/protect.html">Attack</a>
    <br>
    <a href="http://xeseo.blog.163.com/blog/protect.html?<csrf:token uri="protect.html"/>">Protect</a>
    </body>
    </html>
      
    检测到攻击后Redirect的页面(Owasp.CsrfGuard.properties中org.owasp.csrfguard.unprotected.Redirect= xxxxxx配置的): /csrfGuardTest/attackWarn.html
     CSRF Attack Detected!!!
      
    需要保护的页面: http://localhost/csrfGuardTest/protected.html
     This is a protected page!!!
      
    项目结构
    csrfGuardTest
    |
    WebContent
               |
               | ------- index.jsp
               | ------- attackWarn.html
               | ------- protected.html
               | ------- WEB-INF
                                |
                                | --------- Owasp.CsrfGuard.js
                                | --------- Owasp.CsrfGuard.properties
                                | --------- web.xml
                                | --------- lib
                                               | --------- Owasp.CsrfGuard.jar

    打成war包后放到web容器去运行。
    CsrfGuard将页面分为unprotected和protected两种。前者在properties文件配置,后者在web.xml的中指定。所 有的protected页面在访问时uri必须有自动生成的token number作为参数,否则视为攻击,会自动转发到properties文件中配置的页面。
    第一个接受request的页面必须被标记为unprotected,否则在访问该页面时由于被保护,会被自动转发。
    所以,正常情况下,我们要访问protected.html,可以直接访问 http://localhost/csrfGuardTest/protected.html。
    但是,在这里,由于该页面被保护,直接访问就会视为攻击,被自动转发到 attackWarn.html页面。
    index.jsp是保护页面的入口,由于它并未被保护,所以我们能直接从http://localhost/csrfGuardTest/index.jsp访问。里面两个href,一个是正常访问,其实是attack,一个是保护后的访问方式,能够正常访问。

    OWASPGuard自己提供了一个Test程序,可以从这里下载。是一个非常好的例子。
    ---------------------
    作者:Edison徐
    来源:CSDN
    原文:https://blog.csdn.net/xeseo/article/details/9467099
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    29 练习:利用socketserver实现TCP协议下登录认证下载
    28 练习:TCP协议 UDP协议 黏包
    Python基础学习(28)TCP协议的Python实现 UDP协议的Python实现 黏包 利用struct模块解决黏包
    Python 大作业4:选课系统
    Python基础学习(27)网络编程基本概念 C/S架构与B/S架构 OSI七层协议 包的导入
    26 练习题:反射
    Python基础学习(26)classmethod/staticmethod 装饰器 部分内置魔术方法
    25 练习题:super方法 封装 property装饰器 反射
    Python基础学习笔记(25)super方法 封装 property装饰器 反射
    2020 8/10每日日报
  • 原文地址:https://www.cnblogs.com/lirunzhou/p/9909921.html
Copyright © 2020-2023  润新知