How do I send spring csrf token from Postman rest client? - spring

I have csrf protection in spring framework. So in each request I send csrf token in header from ajax call, which is perfectly working.
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
In ajax
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token),
xhr.setRequestHeader("username", "xxxx1"),
xhr.setRequestHeader("password", "password")
}
I haven't any idea to generate csrf token and include in header section of Postman Rest Client ? Would you please help me to send csrf token from Postman Rest Client?

The Easiest way to do this consistently so you don't have to get the token each time:
NOTE:you need to install PostMan Interceptor and activate it to have access to the browsers cookies
Create a new environment so environment variables can be stored
Create a login method with a test to store the XSRF cookie in an environment variable, in the test tab post this code
//Replace XSFR-TOKEN with your cookie name
var xsrfCookie = postman.getResponseCookie("XSRF-TOKEN");
postman.setEnvironmentVariable("xsrf-token", xsrfCookie.value);
EDIT
For anyone using the 5.5.2 postman or later you will also have to decode the cookie, and they have also provided alternative ways to obtain cookies as #Sacapuces points out
pm.environment.set("xsrf-token", decodeURIComponent(pm.cookies.get("XSRF-TOKEN")))
Now you will have an environment variable with xsrf-token in it.
Save your login method
Create the new post you want to create and in the headers add your XSRF-Token-Header Key, and the environment variable in handle bars to access it{{}}
Now before running your new request make sure you run your login, it will store the environment variable, and then when you run the actually request it will automatically append it.

I am able to send REST with csrf token by following the steps below:
The CSRF token generated automatically by spring security when you logged in. It will be shown at the response header.
The CSRF token can be used on subsequent request by setting X-CSRF-TOKEN with CSRF token on header.

Firstly you need to install PostMan Interceptor and activate it to have access to the browsers cookies.
You have to fetch the CSRF Token by making a GET Request:
Header: "XSRF-TOKEN" and Value: "Fetch"
You should see the Token in the cookie tab and can copy it (Notice: You can configure spring how the cookie should be named. Maybe your cookie has another name than "XSRF-TOKEN". Attention: You have the remove this blank char in the token from the newline)
Now make your POST Request and set the header to: Header: "X-XSRF-TOKEN" and Value: "Your copied Token without blanks"

For me works variant with adding X-CSRF-TOKEN to headers.

Please put X-CSRF-Token as key and FETCH as the value in the GET request header and you will receive the token in the response header

If you don't want to configure environment variables etc. here is the quickest solution
https://stackoverflow.com/a/49249850/3705478

I've used csrfTokenRepository() to allow spring security to generate csrf token
#EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// your code
}
}
After adding these lines of code, use GET request to generate csrf token. I've used postman and I got token in the response cookies section. Copy the token and use it in POST call.
Official documentation link :
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html

Related

Disable CSRF for specific URLs SPA Spring Gateway WebFlux

I have next CSRF code in WebFilterChain:
.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
.requireCsrfProtectionMatcher(getURLsForDisabledCSRF())
I would like to turn off the CSRF check on POST methods for several URLs. I have found NegatedServerWebExchangeMatcher, which allows doing next:
return new NegatedServerWebExchangeMatcher(ServerWebExchangeMatchers.pathMatchers(
HttpMethod.POST, "/services/service1/api/some-post-endpoint1",
"/services/service1/api/some-post-endpoint2");
So overall this code works, but when I'm trying to GET request login page or domain page, I will get 'Invalid CSRF' or 'Expected CSRF cannot be found'. Also after Spa tries to redirect me to index.html there will be 403 on this GET redirect the request, which says: Invalid CSRF or no CSRF presented.
When setting the requireCsrfProtectionMatcher you override the default configuration which allows GET requests.
If you want to use both, you can return an AndServerWebExchangeMatcher from getURLsForDisabledCSRF that combines the default CSRF matcher and you custom matcher.
new AndServerWebExchangeMatcher(
CsrfWebFilter.DEFAULT_CSRF_MATCHER,
new NegatedServerWebExchangeMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST,
"/services/service1/api/some-post-endpoint1",
"/services/service1/api/some-post-endpoint2"))
)

Spring Security - CSRF token on GET request

I configured CSRF protection in my Spring 5 (Boot 2) RESTful web service because I want to prevent CSRF attacks (I am using JWT cookie for authentication and authorization). On each request I am getting a new XSRF cookie. The value of that cookie I am sending back through the X-CSRF-TOKEN header.
I noticed that POST, PUT and DELETE methods require the value of this token (in the X-CSRF-TOKEN header) in order to work properly, but GET method works just fine without X-CSRF-TOKEN header.
Is this behavior intentional because GET method should not change state or I did something wrong?
CSRF token is intentionally excluded from GET to avoid token leakage to a 3rd party

Regenerating AntiForgeryToken for form after ajax call

Following asp-net core docs I successfully call my actions using ajax and add the antiforgery token as a header.
Now I want to make this validation "per request". The ajax call is not refreshing the form and the validation token it's the same for all subsequent requests. Which works ok but does not satisfy my security requirements.
I would like to attach to my response a new token, update the form and be sure that once I used a token that is not valid anymore.
To generate a new AntiForgeryToken do the following:
//inject IAntiforgery antiforgery into your class
var antiforgeryTokenSet = antiforgery.GetAndStoreTokens(httpContext);
Then also from your backend code return antiforgeryTokenSet.RequestToken to the client code so that it now has access to the new Request Token. Note the call to GetAndStoreTokens will return the new cookie portion of the antiforgery TokenSet as part of the response. So when the client code sends back the RequestToken in it's next request both parts of the TokenSet will be present and the TokenSet will validate.
You have to call below code on every request:-
var token = antiforgery.GetAndStoreTokens(httpContext);
context.Response.Cookies.Append(requestTokenCookieName, tokens.RequestToken, new CookieOptions()
{
HttpOnly = false,
Secure = true
});
It will create new token and will add it to the response. But calling above code on every request is not all that beneficial.
Please see the below link for more detail on Antiforgery:-
How to implement X-XSRF-TOKEN with angular2 app and net core app?

csrf token without jsp (spring mvc)

I enabled csrf token in config of Spring security. But how mobile device recieve csrf token? When I had jsp, it looked like:
<input type='hidden' name='${_csrf.parameterName}' value='${_csrf.token}'/>
But now I have no jsp... so any way to send csrf manually?
A popular practice is to code a filter to attach the token as a cookie. Your client then sends a GET request first to fetch that cookie. For the subsequent requests, that cookie is then sent back as a header.
You can look at the official Spring Angular guide, and refer to Spring Lemon's source code for a detailed implementation.
You could implement a stateless CSRF protection. One solution nicely explained by Robbert van Waveren is to have the clients generate and send the same unique secret value in both a Cookie and a custom HTTP header:
Considering a website is only allowed to read/write a Cookie for its
own domain, only the real site can send the same value in both
headers. Using this approach all your server has to do is check if
both values are equal, on a stateless per request basis!
You may obtain it by looking inside of the _csrf attribute.
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping("/csrf_token")
public class CsrfTokenController {
#GetMapping
public String getToken(HttpServletRequest request) {
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
return token.getToken();
}
}
If CSRF is enabled, you have to include a _csrf.token in the page you want to login or logout. Otherwise, both login and logout function will be failed.
Refer this for more help.
EDIT: You can get csrf token from request and send it according to your need. I have shared two references for csrf token please go through them. It will help you.
First Ref
Second Ref

Missing CSRF token in REST request

I'm writing a REST API using Spring MVC. I'm trying to access a controller method via a POST request.
I always receive a 403error:
Invalid CSRF Token '' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
How can I deliver a CSRF token within my REST request?
I tried to use the default security password which is displayed during application startup as the value for _csrf but it wasn't successful.
How can I retrieve the CSRF token and is it correct to send the token in the _csrf parameter?
You will need to provide the correct header and CSRF token when making the request e.g.
request.setRequestHeader('${_csrf.headerName}', '${_csrf.token}');
You can also send the token as a request parameter using _csrf.parameterName.

Resources