用什么IE打开建设银行网站,四川省建设执业注册中心网站,客户管理软件哪个好用,vivo手机的网站开发如今#xff0c;随着RESTful架构变得越来越标准#xff0c;可能值得花一些时间重新考虑当前的安全方法。 在这个小系列的博客文章中#xff0c;我们将探索一些以无状态方式解决与Web相关的安全问题的相对较新的方法。 这第一篇文章是关于保护您的网站免受跨站请求伪造#… 如今随着RESTful架构变得越来越标准可能值得花一些时间重新考虑当前的安全方法。 在这个小系列的博客文章中我们将探索一些以无状态方式解决与Web相关的安全问题的相对较新的方法。 这第一篇文章是关于保护您的网站免受跨站请求伪造CSRF的攻击。 总结什么是跨站点伪造 CSRF攻击基于挥之不去的身份验证Cookie。 在登录或以其他方式标识为网站上的唯一访问者之后该网站可能会在浏览器中留下cookie。 如果不显式注销或以其他方式删除此cookie它可能会保持一段时间有效。 另一个站点可以通过使浏览器向受攻击的站点发出跨站点请求来滥用此功能。 例如包括一些用于在“ http://siteunderattack.com/changepassword?pwhacked”标签上进行POST的Javascript将使浏览器发出该请求并将对该域仍然有效的任何身份验证cookie附加到该请求 即使单源策略SOP不允许恶意站点访问响应的任何部分。 从上面的示例中可以很明显地看出如果请求的URL在后台触发任何副作用状态更改则损害已经完成。 常用方法 常用的解决方案是引入所谓的共享秘密CSRF令牌的要求并将其作为先前响应的一部分让客户端知道。 然后对于任何有副作用的请求客户端都必须将其ping回服务器。 可以直接在表单中作为隐藏字段或作为自定义HTTP标头完成此操作。 无论哪种方式其他站点都无法成功产生包含正确CSRF令牌的请求因为SOP阻止跨站点读取来自服务器的响应。 这种方法的问题在于服务器需要记住会话中每个用户的每个CSRF令牌的值。 无状态方法 1.切换到完整且设计正确的基于JSON的REST API。 单源策略仅允许跨站点的HEAD / GET和POST。 POST只能是以下哑剧类型之一application / x-www-form-urlencodedmultipart / form-data或text / plain。 确实没有JSON 现在考虑到GET永远不要在任何经过适当设计的基于HTTP的API中触发副作用这让您可以简单地禁止任何非JSON POST / PUT / DELETE一切都很好。 对于上传文件多部分/表单数据的方案仍然需要明确的CSRF保护。 2.检查HTTP Referer标头。 通过检查仍然易受攻击的场景例如多部分/表单数据POST的Referer标头的存在和内容可以进一步完善上述方法。 浏览器使用此标头来指定触发请求的确切页面url。 这可以轻松地用于检查站点的预期域。 请注意如果选择进行此类检查则在没有标题的情况下切勿允许请求。 3.客户端生成的CSRF令牌。 让客户端在Cookie和自定义HTTP标头中生成并发送相同的唯一秘密值。 考虑到仅允许网站为其自己的域读取/写入Cookie因此只有真实网站才能在两个标头中发送相同的值。 使用这种方法您的服务器要做的就是在每个请求无状态的基础上检查两个值是否相等 实作 着眼于第三种基于显式但基于无状态CSRF令牌的安全性的方法让我们看看使用Spring Boot和Spring Security的代码的外观。 在Spring Boot中您会获得一些不错的默认安全设置您可以使用自己的配置适配器对其进行微调。 在这种情况下所需要做的就是禁用默认的csrf行为并添加自己的StatelessCSRFFilter 自定义CSRF保护 EnableWebSecurity
Order(1)
public class StatelessCSRFSecurityConfig extends WebSecurityConfigurerAdapter {Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().addFilterBefore(new StatelessCSRFFilter(), CsrfFilter.class);}
} 这是StatelessCSRFFilter的实现 自定义CSRF过滤器 public class StatelessCSRFFilter extends OncePerRequestFilter {private static final String CSRF_TOKEN CSRF-TOKEN;private static final String X_CSRF_TOKEN X-CSRF-TOKEN;private final RequestMatcher requireCsrfProtectionMatcher new DefaultRequiresCsrfMatcher();private final AccessDeniedHandler accessDeniedHandler new AccessDeniedHandlerImpl();Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {if (requireCsrfProtectionMatcher.matches(request)) {final String csrfTokenValue request.getHeader(X_CSRF_TOKEN);final Cookie[] cookies request.getCookies();String csrfCookieValue null;if (cookies ! null) {for (Cookie cookie : cookies) {if (cookie.getName().equals(CSRF_TOKEN)) {csrfCookieValue cookie.getValue();}}}if (csrfTokenValue null || !csrfTokenValue.equals(csrfCookieValue)) {accessDeniedHandler.handle(request, response, new AccessDeniedException(Missing or non-matching CSRF-token));return;}}filterChain.doFilter(request, response);}public static final class DefaultRequiresCsrfMatcher implements RequestMatcher {private final Pattern allowedMethods Pattern.compile(^(GET|HEAD|TRACE|OPTIONS)$);Overridepublic boolean matches(HttpServletRequest request) {return !allowedMethods.matcher(request.getMethod()).matches();}}
} 不出所料无状态版本在两个标头值上只做一个简单的equals。 客户端实施 客户端实现也很简单尤其是在使用AngularJS时。 AngularJS已经提供了内置的CSRF令牌支持。 如果您告诉它要读取的cookie它将自动将其值发送到您选择的自定义标头中。 浏览器负责发送cookie标头本身。 您可以按以下方式覆盖AngularJS的默认名称XSRF而不是CSRF 设置适当的令牌名称 $http.defaults.xsrfHeaderName X-CSRF-TOKEN;
$http.defaults.xsrfCookieName CSRF-TOKEN; 此外如果您想为每个请求生成一个新的令牌值则可以将自定义拦截器添加到$ httpProvider中如下所示 拦截器生成cookie app.config([$httpProvider, function($httpProvider) {//fancy random token, losely after https://gist.github.com/jed/982883function b(a){return a?(a^Math.random()*16a/4).toString(16):([1e16]1e16).replace(/[01]/g,b)};$httpProvider.interceptors.push(function() {return {request: function(response) {// put a new random secret into our CSRF-TOKEN Cookie before each requestdocument.cookie CSRF-TOKEN b();return response;}};});
}]); 您可以在github上找到一个完整的可用示例。 确保已安装gradle 2.0并使用“ gradle build”和“ gradle run”简单地运行它。 如果要像eclipse一样在IDE中使用它请使用“ gradle eclipse”只需从IDE内导入并运行它即可无需服务器。 免责声明 有时经典的CSRF令牌被错误地视为针对重播或暴力攻击的解决方案。 此处列出的无状态方法未涵盖此类攻击。 我个人认为这两种类型的攻击都应从另一个角度进行考虑例如使用https和速率限制。 对于公开网站上的任何数据输入我俩都认为这是必须的 翻译自: https://www.javacodegeeks.com/2014/10/stateless-spring-security-part-1-stateless-csrf-protection.html