CSRF
CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
攻击示例
如:一个网站用户Bob可能正在浏览聊天论坛,而同时另一个用户Alice也在此论坛中,并且后者刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片src。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。
CSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。
下面是CSRF的常见特性:
依靠用户标识危害网站
利用网站对用户标识的信任
欺骗用户的浏览器发送HTTP请求给目标站点
另外可以通过IMG标签会触发一个GET请求,可以利用它来实现CSRF攻击。
spring mvc 框架下防御策略
思路概要:
1.初始化页面时在token隐藏域。
2.表单提交后带入token到后台,验证token,如成功继续操否为受到攻击。
3.操作完之后重新生成token到页面隐藏域。
代码示例:
创建拦截器:
/**
* <一句话功能简述>
* <功能详细描述>
* 防止跨站请求伪造拦截器
* 为每个返回的页面添加CSRFToken参数
* @author Tangguilin
* @version [版本号, 2016年3月26日]
*/
public class AvoidCSRFInterceptor extends HandlerInterceptorAdapter
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception
{
String url = request.getRequestURI();
if (!url.endsWith(".do"))
{
return true;
}
HandlerMethod handlerMethod = (HandlerMethod)handler;
Method method = handlerMethod.getMethod();
VerifyCSRFToken annotation = method.getAnnotation(VerifyCSRFToken.class);
if (annotation != null)
{
String xrq = request.getHeader("X-Requested-With");//是否为Ajax标志
//非法的跨站请求校验
if (annotation.verifyCSRFToken() && !verifyCSRFToken(request))
{
if (StringUtil.isEmpty(xrq))
{
//form表单提交,url get方式,刷新csrftoken并跳转提示页面
request.getSession(false).setAttribute("CSRFToken",
TokenProcessor.getInstance().generateToken(request));
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("非法请求");
response.flushBuffer();
return false;
}
else
{
//刷新CSRFToken,返回错误码,用于ajax处理,可自定义