http://blog.csdn.net/xeseo/article/details/9467099
一. 什么是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建议两种并用。
<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> |
<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> |
<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)
<%@ 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> |
CSRF Attack Detected!!! |
This is a protected page!!! |