CSRF攻击防范
2016-09-01 10:17
274 查看
CSRF全称:(Cross-site request forgery)跨域请求伪造
理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求
对于CSRF概念的理解:http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
以下是自己的总结与实现方式(拦截器实现):
CSRF攻击必须依次完成以下两个条件:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了
CSRF攻击形成的原因:
1.网站违反了HTTP协议,使用GET请求更新资源(非常危险).
2.使用无校验的表单
CSRF攻击是源于WEB的隐式身份验证机制!(比如你在A网站登录后,在同一个浏览器的tab页打开B网站网页, 而B网站网页有一些脚本链接到A网站并偷偷的发送请求更新你账号的信息.如果没有防CSRF攻击,这样是可以实现的.)
WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
CSRF防范方式:客户端页面增加伪随机数。每次需要修改该用户的数据库信息时必须带上该随机数,否则不受理.
解决办法: 在Form表单加一个hidden field,里面是服务端生成的足够随机数的一个Token(恶意网站猜不到也无法获取到相同的Token), 然后使用一个拦截器interceptor来检查每一个非get请求, 看该token与服务器token是否一致,不一致的不受理该请求.
以下是token 的工具管理类:
后台返回token参数给页面:
页面使用隐藏域保存起来:
编写代码要符合HTTP规范,不要使用GET请求更新资源
在非GET请求中带上token 参数(ajax请求也要),然后使用拦截器检查.
(对于受到CSRF攻击我使用的是抛自定义异常,然后使用springmvc全局异常进行处理,您如果想了解springmvc全局异常处理可以看我博客.)
在spring的配置文件中添加拦截器使其生效
有问题欢迎留言. 相互探讨相互学习.
理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求
对于CSRF概念的理解:http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
以下是自己的总结与实现方式(拦截器实现):
CSRF攻击必须依次完成以下两个条件:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了
CSRF攻击形成的原因:
1.网站违反了HTTP协议,使用GET请求更新资源(非常危险).
2.使用无校验的表单
CSRF攻击是源于WEB的隐式身份验证机制!(比如你在A网站登录后,在同一个浏览器的tab页打开B网站网页, 而B网站网页有一些脚本链接到A网站并偷偷的发送请求更新你账号的信息.如果没有防CSRF攻击,这样是可以实现的.)
WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
CSRF防范方式:客户端页面增加伪随机数。每次需要修改该用户的数据库信息时必须带上该随机数,否则不受理.
解决办法: 在Form表单加一个hidden field,里面是服务端生成的足够随机数的一个Token(恶意网站猜不到也无法获取到相同的Token), 然后使用一个拦截器interceptor来检查每一个非get请求, 看该token与服务器token是否一致,不一致的不受理该请求.
以下是token 的工具管理类:
package com.xxx.xxx.util; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.UUID; /** * CSRFtoken管理类 * * @author 作者 yss * @version 版本号 v1.0 */ public final class CSRFTokenManager { /** * 约定规范:表单提交时的token的input的name属性必须为该值才能获取到后台返回的token。 * 下面是使用EL表达式接收从后台返回的token参数 * 如: <input type="hidden" id="CSRFToken" value="${CSRFToken}"> */ public static final String CSRF_PARAM_NAME = "CSRFToken"; /** * 存放在session中的token名称(跟上面的name属性值不一定一样) */ public static final String CSRF_TOKEN_FOR_SESSION_ATTR_NAME = CSRFTokenManager.class.getName() + ".tokenval"; /** *从session中获取token字符串 * @param session * @return */ public static String getTokenForSession(HttpSession session) { String token = null; //保证session只存在一个token,避免多线程情况下产生冲突。 synchronized (session) { token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME);//尝试获取session中的token if (null == token) {//如果session中没有token,就重新生成一个token token = UUID.randomUUID().toString(); session.setAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME, token); } } return token; } /** *获取到request中的token值。 * @param request * @return */ public static String getTokenFromRequest(HttpServletRequest request) { return request.getParameter(CSRF_PARAM_NAME); } //构造器 private CSRFTokenManager() { } }
后台返回token参数给页面:
String token = CSRFTokenManager.getTokenForSession(request.getSession());//uuid生成的随机token modelAndView.addObject(CSRFTokenManager.CSRF_PARAM_NAME, token);//添加token参数
页面使用隐藏域保存起来:
<input type="hidden" id="CSRFToken" value="${CSRFToken}"><%--token--%>
编写代码要符合HTTP规范,不要使用GET请求更新资源
在非GET请求中带上token 参数(ajax请求也要),然后使用拦截器检查.
(对于受到CSRF攻击我使用的是抛自定义异常,然后使用springmvc全局异常进行处理,您如果想了解springmvc全局异常处理可以看我博客.)
package com.xxx.xxx.interceptor; import com.xxx.xxx.exception.CSRFException; import com.xxx.xxx.util.CSRFTokenManager; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 对于未登录用户的请求进行拦截,确保用户已经登录,然后进行后续的网页请求 * * @Author yss * @Version 1.0 * @see */ public class CSRFInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Enumeration parasm = request.getParameterNames(); if (!"GET".equals(request.getMethod())) {//非get请求 String CSRFToken = CSRFTokenManager.getTokenFromRequest(request);//页面传过来的csrf参数 if (CSRFToken == null || !CSRFToken.equals(CSRFTokenManager.getTokenForSession(request.getSession()))) {//token不对应 throw new CSRFException("CSRF攻击");//抛异常后将会进入springmvc全局异常处理体系 } } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { super.postHandle(request, response, handler, modelAndView); } }
在spring的配置文件中添加拦截器使其生效
<mvc:interceptors> <!-- 防止CSRF攻击的拦截器 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean id="CSRFInterceptor" class="com.xxx.xxx.interceptor.CSRFInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
有问题欢迎留言. 相互探讨相互学习.
相关文章推荐
- CSRF攻击和防范
- ci框架如何手动进行csrf攻击防范
- CSRF攻击防范
- YII2框架学习 安全篇(三) csrf攻击和防范
- CSRF的攻击和防范
- CSRF攻击介绍、模拟、防范
- CSRF攻击的原理及防范
- web安全之跨站请求伪造攻击(CSRF)与防范方法
- 浅谈csrf攻击以及yii2对其的防范措施
- 同步令牌模式防范CSRF跨站请求伪造攻击
- php web开发安全之csrf攻击的简单演示和防范(一)
- 来了解并防范一下CSRF攻击提高网站安全
- CSRF攻击方式和防范措施
- csrf攻击与防范
- PHP开发中csrf攻击的简单演示和防范
- CSRF攻击防范
- csrf攻击及其防范介绍
- IIS 服务器 防范攻击3条安全设置技巧
- CSRF攻击:简单服务器防御
- CSRF攻击与防御