手记_Spring Security

目录

Spring Security手记

内容

CSRF防护

重定向循环


Spring Security手记

内容

CSRF防护

CSRF,全称为Cross-Site Request Forgery,跨站请求伪造,是一种网络攻击方式,它可以在用户毫不知情的情况下,以用户的名义伪造请求发送给被攻击站点,从而在未授权的情况下进行权限保护内的操作。

具体来讲,可以这样理解CSRF。攻击者借用用户的名义,向某一服务器发送恶意请求,对服务器来讲,这一请求是完全合法的,但攻击者确完成了一个恶意操作,比如以用户的名义发送邮件,盗取账号,购买商品等等。

简单来说,CSRF必须经过两个步骤:

1、用户访问可信任站点A,并产生了相关的cookie;

2、用户在访问A站点时没有退出,同时访问了危险站点B。

CSRF能成功是因为同一个浏览器会共享Cookies,也就是说,通过权限认证和验证是无法防止CSRF的。

那么应该怎样防止CSRF呢?其实防止CSRF的方法很简单,只要确保请求是自己的站点发出的就可以了。目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证(表单令牌验证);在 HTTP 头中自定义属性并验证。

1、尽量使用POST,限制GET

GET接口太容易被拿来做CSRF攻击,看第一个示例就知道,只要构造一个img标签,而img标签又是不能过滤的数据。

接口最好限制为POST使用,GET则无效,降低攻击风险。

当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。

2、加验证码

验证码,强制用户必须与应用进行交互,才能完成最终请求。在通常情况下,验证码能很好遏制CSRF攻击。

但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。

3、Referer Check

Referer Check在Web最常见的应用就是“防止图片盗链”。

同理,Referer Check也可以被用于检查请求是否来自合法的“源”(Referer值是否是指定页面,或者网站的域),如果都不是,那么就极可能是CSRF攻击。

但是因为服务器并不是什么时候都能取到Referer,所以也无法作为CSRF防御的主要手段。

但是用Referer Check来监控CSRF攻击的发生,倒是一种可行的方法。

4 、Anti CSRF Token

CSRF攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都存在cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的cookie来通过安全验证。要防止CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于cookie之中。可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器建立一个拦截器来验证这个token,如果请求中没有token或者token不正确,则认为可能是CSRF攻击而拒绝该请求。

现在业界对CSRF的防御,一致的做法是使用一个Token(Anti CSRF Token)。

例子:

用户访问某个表单页面。

服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。

在页面表单附带上Token参数。

用户提交请求后, 服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。

这个Token的值必须是随机的,不可预测的。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token时应注意Token的保密性,尽量把敏感操作由GET改为POST,以form或AJAX形式提交,避免Token泄露。

https://docs.spring.io/spring-security/site/docs/3.2.3.RELEASE/reference/htmlsingle/#the-csrfInput-tag

6.2. Synchronizer Token Pattern

To protect against CSRF attacks we need to ensure there is something in the request that the evil site is unable to provide.

our solution is to use the Synchronizer Token Pattern(令牌同步模式). This solution is to ensure that each request requires, in addition to our session cookie, a randomly generated token as an HTTP parameter. When a request is submitted, the server must look up the expected value for the parameter and compare it against the actual value in the request. If the values do not match, the request should fail.

We can relax the expectations to only require the token for each HTTP request that updates state. This can be safely done since the same origin policy(同源策略) ensures the evil site connot read the response. Additonally, we do not want to include the random token in HTTP GET as this can cause the tokens to be leaked.

When you use CSRF protection? Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.

 

Using Spring Security CSRF Protection

  1. Use proper HTTP verbs
  2. Configure CSRF Protection
  3. Include the CSRF Token

 

  1. The first step to protecting against CSRF attacks is to ensure your website uses proper HTTP verbs. Specifically, before Spring Security’s CSRF support can be of use, you need to be certain that your application is using PATCH, POST, PUT, and/or DELETE for anything that modifies state.
  2. The next step is to include Spring Security’s CSRF protection within your application. Some frameworks handle invalid CSRF tokens by invaliding the user’s session(会话无效), but this causes its own problems. Instead by default Spring Security’s CSRF protection will produce an HTTP 403 access denied. This can be customized by configuring the AccessDeniedHandler to process InvalidCsrfTokenException differently.( 这可以通过配置AccessDeniedHandler以不同方式处理InvalidCSRFtokenException来定制。)

For passivity reasons, if you are using the XML configuration, CSRF protection must be explicitly enabled using the <csrf> element.

CSRF protection is enabled by default with Java configuration. if you would like to disable CSRF, the need:

 

  1. Form Submissions.

The alst step is to ensure that you include the CSRF token in all PATCH, POST, PUT, and DELETE methods. One way to approach this is use the _csrf request attribute to obtain the current CsrfToken. following:

 

An easier approach is to use the csrfInput tag from the Spring Security JSP atg library.

If you are using Spring MVC <form:form> tag or Thymeleaf 2.1+, and you replace @EnableWebSecurity with @EnableWebMvcSecurity, the CsrfToken is automatically included for you (using the CsrfRequestDataValueProcessor).

Ajax and JSON Requests

If you using JSON, then it is not possible to submit the CSRF token within an HTTP parameter. Instead you can submit the token within a HTTP header. A typical pattern would be to include the CSRF token within your meta tags. An example with a JSP is shown below:

 

Instead of manually creating the meta tags, you can use the simpler csrfMetaTags tag from the Spring Security JSP tag library.

************************************************************************************************

 

<!DOCTYPE html>

<html>

    <head>

        <title>CSRF Protected JavaScript Page</title>

        <meta name="description" content="This is the description for this page" />

        <sec:csrfMetaTags />

        <script type="text/javascript" language="javascript">

 

            var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");

            var csrfHeader = $("meta[name='_csrf_header']").attr("content");

            var csrfToken = $("meta[name='_csrf']").attr("content");

 

            // using XMLHttpRequest directly to send an x-www-form-urlencoded request

            var ajax = new XMLHttpRequest();

            ajax.open("POST", "http://www.example.org/do/something", true);

            ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded data");

            ajax.send(csrfParameter + "=" + csrfToken + "&name=John&...");

 

            // using XMLHttpRequest directly to send a non-x-www-form-urlencoded request

            var ajax = new XMLHttpRequest();

            ajax.open("POST", "http://www.example.org/do/something", true);

            ajax.setRequestHeader(csrfHeader, csrfToken);

            ajax.send("...");

 

            // using JQuery to send an x-www-form-urlencoded request

            var data = {};

            data[csrfParameter] = csrfToken;

            data["name"] = "John";

            ...

            $.ajax({

                url: "http://www.example.org/do/something",

                type: "POST",

                data: data,

                ...

            });

 

            // using JQuery to send a non-x-www-form-urlencoded request

            var headers = {};

            headers[csrfHeader] = csrfToken;

            $.ajax({

                url: "http://www.example.org/do/something",

                type: "POST",

                headers: headers,

                ...

            });

 

        <script>

    </head>

    <body>

        ...

    </body>

</html>

************************************************************************************************

 

You can then include the token within all your Ajax requests. If you were using jQuery, this could be done with the following:

 

As a alternative to jQuery, we recommend using cujoJS’s rest.js. The rest.js module provides advanced support for working with HTTP request and responses in RESTful ways. A core capability is the ability to contextualize the HTTP client adding behavior as needed by chaining interceptors on to the client.

 

The configured client can be shared with any component of the application that needs to make a request to the CSRF protected resource. One significant different between rest.js and jQuery is that only requests made with the configured client will contain the CSRF token, vs jQuery where all requests will include the token. The ability to scope which requests receive the token helps guard against leaking the CSRF token to a third party. Please refer to the rest.js reference documentation for more information on rest.js.

       The next section: 6.5. CSRF Caveats

重定向循环

问题

https://img-blog.csdn.net/20171026172241314?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcTEwNTQyNjE3NTI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

 

反复重定向出现

原因

没有将登录页设置权限,即自定义的登录页也需要权限才能访问,所以一直跳转到登录页,而登录页就是自己本身。
 

解决

 

将登录页设置允许无条件登录:

http.authorizeRequests().antMatchers("/login", "/logout").permitAll();

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值