如今,随着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

无状态Spring安全性第1部分:无状态CSRF保护相关推荐

  1. spring期刊状态_无状态Spring安全性第2部分:无状态认证

    spring期刊状态 Spring Stateless Security系列的第二部分是关于以无状态方式探索身份验证的方法. 如果您错过了有关CSRF的第一部分,可以在这里找到. 因此,在谈论身份验证 ...

  2. csrf spring_无状态Spring安全性第1部分:无状态CSRF保护

    csrf spring 如今,随着RESTful架构变得越来越标准,可能值得花一些时间重新考虑当前的安全方法. 在这一小系列博客文章中,我们将探索以无状态方式解决与Web相关的安全性问题的几种相对较新 ...

  3. 无状态Spring安全性第2部分:无状态身份验证

    Spring Stateless Security系列的第二部分是关于以无状态方式探索身份验证的方法. 如果您错过了CSRF的第一部分,可以在这里找到. 因此,在谈论身份验证时,其全部内容就是让客户端 ...

  4. 无csrf防护的html页面,Springs CSRF保护仅* HTML登录页面

    我正在尝试利用Spring Security内置的CSRF保护.这些是我正在使用的spring版本: Spring Framework版本-4.2.1 spring安全-4.0.2 Spring安全性 ...

  5. 关于无状态服务(stateless service) 有状态服务(stateful service),指一篇文章就搞明白

    无状态服务(stateless service) 一.定义 无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求 ...

  6. 美团无人车收到首张罚单 低速无人车到底该怎么管?

    前两天,北京顺义一辆私家车与一辆美团无人配送车发生交通事故,交警勘查现场后判定美团无人配送车负全部责任,并开出罚单.这也是国内公开报道中首例针对无人配送车开出的罚单. 截止目前,美团并未就事故经过展开 ...

  7. spring安全性_具有PreAuthorize的Spring方法安全性

    spring安全性 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 本教程将探讨使 ...

  8. 无线充电动牙刷PCBA单片机方案牙刷无线充底座IC芯片

    泛海微无线充电动牙刷PCBA单片机方案牙刷无线充底座IC芯片 FS68001/FS68004产品概述:  无线接收和马达控制 无线发射:  芯片型号 FS68001/FS68004  1.主机功耗最大 ...

  9. 无盘服务器配置网众,网众无盘服务端工作站设置

    之前我们txwb网吧无盘曾介绍了网众无盘的安装,现在我们要说明的是网众无盘服务端工作站设置,下面大家就和我们一起去瞧瞧吧! 工作站设置部分需要说明的地方是启动选项部分,包括启动时候删除工作文件和支持网 ...

最新文章

  1. CGIC简明教程(转摘)
  2. Xen之初体验:HA(额外附加)
  3. PyCharm+QT Designer整合
  4. Java常用类之String类练习
  5. 使用 Boost.MPI 的 split() 操作对通信器的示例
  6. JS 内置对象 String对象
  7. 文本强制不换行并隐藏
  8. Lombok ——自动化方法生成器
  9. Visual Studio、.NET Framework、VC++、C#各个版本的对应关系
  10. 6个好用的Web开发工具
  11. ef mysql 中文乱码,mysql解決中文亂碼問題
  12. 中国范围NPP-VIIRS逐年夜间灯光数据(2013-2020年)
  13. linux设置ipsan_linux挂载ipsan服务器
  14. 计算机数据链路层教案,4.1数据链路层作用教案(计算机网络技术基础教案).doc...
  15. 一个可以免费下载英文书籍的网站
  16. Latex排版技巧:上下方可输入文字的箭头
  17. vue项目实现更换默认头像功能
  18. CSS画出半圆,四分之一圆,三角等图形
  19. 《Python编程:从入门到实践》 练习 9-4 9-5
  20. 读电子书微习惯的养成

热门文章

  1. zookeeper出现Error contacting service. It is probably not running.
  2. datatable中某一列最小值_获取DataTable 某一列所有值
  3. mybatis generator Unknown system variable 'query_cache_size' 的解决方法
  4. mega x_[MEGA DEAL]通过Hadoop Bundle掌握大数据(91%的折扣)
  5. 2019 java值得学吗_Java认证值得吗?
  6. crud-table_我个人的CRUD故事-或我如何来到CUBA平台
  7. eap aka_使用API​​密钥(aka身份验证令牌)部署到Maven Central
  8. java循坏_Java的坏功能是什么
  9. javabeans_(单元测试)JavaBeans的技巧
  10. junit:junit_简而言之,JUnit:测试隔离