Spring Security blocks POST requests despite SecurityConfig

后端 未结 3 1073
囚心锁ツ
囚心锁ツ 2021-02-12 15:27

I\'m developing a REST API based on Spring Boot (spring-boot-starter-web) where I use Spring Security (spring-security-core e spring-security-con

3条回答
  •  别跟我提以往
    2021-02-12 16:09

    Cross-site request forgery is a web security vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform.

    In your case disabling CSRF protection exposes user to this vulnerability.

    Note: If it was pure Rest API with O-Auth protection then CSRF was not needed. Should I use CSRF protection on Rest API endpoints?

    But In your case when user logs in a session is created and cookie is returned in response and without CSRF token Attacker can exploit it and perform CSRF.

    It wouldn't be a good idea to disable CSRF instead you can configure your app to return CSRF token in response headers and then use it in all your subsequent state changing calls.

    Add this line of code in your SecurityConfiguration.java

    // CSRF tokens handling
    http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
    

    CsrfTokenResponseHeaderBindingFilter.java

    public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter {
        protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf";
        protected static final String RESPONSE_HEADER_NAME = "X-CSRF-HEADER";
        protected static final String RESPONSE_PARAM_NAME = "X-CSRF-PARAM";
        protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN";
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {
            CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME);
    
            if (token != null) {
                response.setHeader(RESPONSE_HEADER_NAME, token.getHeaderName());
                response.setHeader(RESPONSE_PARAM_NAME, token.getParameterName());
                response.setHeader(RESPONSE_TOKEN_NAME, token.getToken());
            }
    
            filterChain.doFilter(request, response);
        }
    }
    

    Header Response form Server:

    Note that we now have CSRF token in the header. This will not change untill the session expires. Also read: Spring Security’s CSRF protection for REST services: the client side and the server side for better understanding.

提交回复
热议问题