Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put CSRF into Headers in Spring 4.0.3 + Spring Security 3.2.3 + Thymeleaf 2.1.2

I have the following code:

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta name="_csrf" th:content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
    <title>Fileupload Test</title>
</head>
<body>

<p th:text="${msg}"></p>

<form action="#" th:action="@{/fileUpload}" method="post" enctype="multipart/form-data">
    <input type="file" name="myFile"/>
    <input type="submit"/>
</form>

</body>
</html>

I get the error HTTP 403:

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'

CSRF is working if I use this line instead:

<form action="#" th:action="@{/fileUpload} + '?' + ${_csrf.parameterName} + '=' + ${_csrf.token}" method="post" enctype="multipart/form-data">

But how can I achieve working CSRF if I use headers?

like image 201
user2000811 Avatar asked May 05 '14 16:05

user2000811


People also ask

How do I get CSRF token in Spring Security?

You can obtain the CSRF using the request attribute named _csrf as outlined in the reference. To add the CSRF to an HTML page, you will need to use JavaScript to obtain the token that needs to be included in the requests.

How does CSRF work in Spring Security?

To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.

How does Spring generate CSRF token?

In Spring Security, the CSRF tokens are generated per session. When a session starts, a CSRF token is generated. If the session changes or times out, a new CSRF token will be returned by the server. The first GET request fails because we're not authenticated.


2 Answers

After fighting with this issue for some time, I finally figured out why the code in the official Spring documentation doesn't work... Notice the following:

<meta name="_csrf" content="${_csrf.token}" />
<meta name="_csrf_header" content="${_csrf.headerName}" />

This is documentation with JSP in mind! Since we are using Thymeleaf, what you need to do is to use th:content instead of content:

<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

Now it works!

like image 80
goncalotomas Avatar answered Oct 06 '22 20:10

goncalotomas


<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

and

var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });

$.ajax({
url: url,
method: 'DELETE',
success: function(result) {
    $('#table').bootstrapTable('remove', {
        field: 'id',
        values: [row.id]
    });
},
    error:function(result) {
    console.log(result);
}

});

Solved a problem with jquery ajax request delete .I use Spring Boot , Security and bootstrap -table .

like image 29
Adriano Faria Alves Avatar answered Oct 06 '22 18:10

Adriano Faria Alves