无状态Spring安全性第1部分:无状态CSRF保护

如今,随着RESTful架构变得越来越标准,可能值得花一些时间重新考虑当前的安全方法。 在这个小系列的博客文章中,我们将探索一些以无状态方式解决与Web相关的安全问题的相对较新的方法。 这第一篇文章是关于保护您的网站免受跨站请求伪造(CSRF)的攻击。

总结:什么是跨站点伪造?

CSRF攻击基于挥之不去的身份验证Cookie。 在登录或以其他方式标识为网站上的唯一访问者之后,该网站可能会在浏览器中留下cookie。 如果不显式注销或以其他方式删除此cookie,它可能会保持一段时间有效。

另一个站点可以通过使浏览器向受攻击的站点发出(跨站点)请求来滥用此功能。 例如,包括一些用于在“ http://siteunderattack.com/changepassword?pw=hacked”标签上进行POST的Javascript,将使浏览器发出该请求,并将对该域仍然有效的任何(身份验证)cookie附加到该请求!

即使单源策略(SOP)不允许恶意站点访问响应的任何部分。 从上面的示例中可以很明显地看出,如果请求的URL在后台触发任何副作用(状态更改),则损害已经完成。

常用方法

常用的解决方案是引入所谓的共享秘密CSRF令牌的要求,并将其作为先前响应的一部分让客户端知道。
然后,对于任何有副作用的请求,客户端都必须将其ping回服务器。 可以直接在表单中作为隐藏字段或作为自定义HTTP标头完成此操作。 无论哪种方式,其他站点都无法成功产生包含正确CSRF令牌的请求,因为SOP阻止跨站点读取来自服务器的响应。 这种方法的问题在于服务器需要记住会话中每个用户的每个CSRF令牌的值。

无状态方法

1.切换到完整且设计正确的基于JSON的REST API。

单源策略仅允许跨站点的HEAD / GET和POST。 POST只能是以下哑剧类型之一:application / x-www-form-urlencoded,multipart / 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()*16>>a/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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

window.Event参数详解

原文地址:window.Event参数详解作者:cz0090704window.evet 说明 event代表事件的状态,例如触发event对象的元素、鼠标的位置及状态、按下的键等等。 event对象只在事件发生的过程中才有效。 event的某些属性只对特定的事件有意义。比如&…

微信群运营之设计运营思路

商家要想运营好微信群,那么首要做的工作就是设计运营思路。如果做事毫无章法思路,那么很有可能会让自己的工作陷入僵局。运营微信群并不简单,需要考虑多方面社群鸭因素。卖什么产品,群管理体系的设立,规则的制定&#…

阅读react-redux源码(七) - 实现一个react-redux

阅读react-redux源码 - 零阅读react-redux源码 - 一阅读react-redux源码(二) - createConnect、match函数的实现阅读react-redux源码(三) - mapStateToPropsFactories、mapDispatchToPropsFactories和mergePropsFactories阅读react-redux源码(四) - connectAdvanced、wrapWithC…

[读书笔记]TCP/IP详解V1读书笔记-4 5

IP地址与以太网地址之间的关系 R P发送一份称作A R P请求的以太网数据帧给以太网上的每个主机。这个过程称作广播,在32 bit的I P地址和采用不同网络技术的硬件地址之间提供动态映射 ----------------------------------------- arp以太网帧的类型字段为x 0 8 0 6&am…

未来是Apache Karaf上的微服务架构

这是Jamie Goodyear的客座博客文章( 博客 , icbts )。 他是Savoir Technologies的开源倡导者,Apache开发人员和计算机系统分析师; 他为全球大型组织设计,批判和支持了体系结构。 他拥有纽芬兰纪念大学的计…

springcloud微服务多节点高性能、高可用、高并发部署

1. 共有三个服务 discovery服务,domain服务,gateway服务。 discovery服务是用来注册其他服务的,作为服务治理用。 domain服务是主业务服务。 gateway服务是所有服务的一个入口,用来做一些服务的判断和过滤用。 2. 有三台机器分别为…

只能是数字、字母、-和_

在文本框的keypress事件调用下面函数。 如 <input disabled"disabled" type"text" iduserNameToEdit οnkeypress"TextValidate()" /> 如果在文本框中按下特殊字符键&#xff0c;则显示警告信息&#xff0c;或者输入框不接受非法输入。 …

代码风格之Prettier简介

多人协作中统一的代码风格有利于项目的发展这是共识&#xff0c;但是采用什么标准来统一代码这选择就相对纷杂。项目刚开始使用了ESLint来规范代码&#xff0c;但是ESLint默认是支持JavaScript&#xff0c;加上配置可以支持TypeScript&#xff0c;而样式的支持则需要再配置Styl…

带有Swagger的Spring Rest API –集成和配置

如今&#xff0c;公开的API终于获得了应有的关注&#xff0c;公司也开始意识到其战略价值。 但是&#xff0c;使用第三方API确实是一项繁琐的工作&#xff0c;尤其是当这些API维护不当&#xff0c;设计不当或缺少任何文档时。 这就是为什么我决定四处寻找可以为集成编程人员和其…

A customized combobox with JQuery

要求实现一个轻量级的在客户端筛选的combobox&#xff0c;支持大数据量&#xff08;超过1000个items&#xff09;&#xff0c;能快速检索内容&#xff0c;并支持数据的设置和活动等基本操作。在这之前尝试过使用Jquery UI的Autocomplete&#xff0c;但是当数据量太大时客户端检…

使用内存回流的方法来实现将image的内容转换为 byte[]

在今天的开发中老大不知道怎么突发奇想&#xff0c;要使用Image的Byte数据。当时使用老几种方式效果均不理想&#xff0c;最后发现其实可以使用内存回流的方式来实现。多的不说老&#xff0c;马上贴上代码&#xff1a;/**//// <summary> /// 将byte[]转换为Image…

TypeScript中的class声明了什么

在初看TypeScript的时候在这里卡住的时间难以估计&#xff0c;并不能很好的理解”换个角度说&#xff0c;我们可以认为类具有 实例部分与 静态部分这两个部分。“这句话。今天再回头看这部分文档&#xff0c;在同事的帮助下突然有了比较通透的理解。 class Greeter {static st…

CentOS 6下搭建Apache+MySQL+PHP+SSL

网上的一些文章都已经比较老了&#xff0c;现在版本高了之后&#xff0c;其实配置是很省力的&#xff08;不考虑什么负载的话&#xff09; 分享全过程&#xff0c;出了文中提到的安装epel rpmfushion 源指令不同外&#xff0c;其他的过程也适用与Centos 5 1.安装CentOS 6 ,可以…

通过设计国际象棋游戏来了解策略模式

今天&#xff0c;我们将借助一个示例来尝试了解策略模式。 我们将考虑的示例是国际象棋游戏。 这里的目的是解释策略模式&#xff0c;而不是构建全面的国际象棋游戏解决方案。 策略模式&#xff1a;策略模式被称为行为模式-用于管理对象之间的算法&#xff0c;关系和职责。 策…

vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 在安装 VS2010 后&#xff0c;再安装 VS2012 VS2015 等&#xff0c;原来的 .NET 4.0 会被替换为 .NET 4.5。不会恢复 .NET 4.0 。这时&#xff0c;VS2010的 cvtres.exe 就无法使用了。如果 PATH…

Nginx 使用try_files遇到的问题

背景&#xff1a; root /some/path; location / {try_files $uri $uri/ /dist/index.html; }使用React之类的的库来开发前端页面的时候&#xff0c;因为是单页应用所以需要上面的Nginx配置&#xff0c;用来在找不到html文件的时候内部重定向到/dist/index.html文件。 服务器上…

群发邮件

最近&#xff0c;通过两周的学习&#xff0c;对.net 的基础知识有了进一步的了解。觉得自己可以写个小程序了。于是花了两天时间写了一个 群发邮件的一个WinForm小程序。自己在这里小秀一下&#xff0c;表扬及鼓励一下自己。哈哈&#xff01; 此小程序在发送邮件的基础上还添加…

深入研究ES6 Generators

ES6 Generators系列&#xff1a; ES6 Generators基本概念深入研究ES6 GeneratorsES6 Generators的异步应用ES6 Generators并发 如果你还不知道什么是ES6 generators&#xff0c;请看我的前一篇文章“ES6 Generators基本概念” 。如果你已经对它有所了解&#xff0c;本文将带你…

在JavaEE中使用CDI的简单面向方面的编程(AOP)

我们编写满足特定业务逻辑的服务API。 涵盖所有服务API&#xff08;如安全性&#xff0c;日志记录&#xff0c;审核&#xff0c;度量延迟等&#xff09;的跨领域问题很少。 这是一个重复的非业务代码&#xff0c;可以在其他方法之间重用。 重用的一种方法是将这些重复的代码移入…

sessionStorage什么时候失效

最近在调试程序的时候无意间看到 cookie 的过期时间是 session&#xff0c;这个 session 表示的是什么时候过期&#xff1f;牵扯出来另一个存储方案 sessionStorage 存储的数据又是什么时候过期呢&#xff1f; 在查找相关资料的时候总会看到会话结束的时候 cookie 会被清除&am…