The new CookieCsrfTokenRepository creates a new cookie in org.springframework.security.web.csrf.CookieCsrfTokenRepository.saveToken(CsrfToken, HttpServletRequest, HttpServletResponse).
This cookie should be httpOnly by default- the setting should be configurable.
At the moment the cookie has no httpOnly flag.
The cookie should have the httpOnly flag by default and should be configurable when creating the CookieCsrfTokenRepository
CookieCsrfTokenRepository csrfTokenRepository = new CookieCsrfTokenRepository();
csrfTokenRepository.setCookieName(CsfSecurityConfiguration.csrfTokenCookieName);
// proposal to configure the httpOnly flag...
csrfTokenRepository.setCookieHttpOnly(true);
http.csrf().csrfTokenRepository(csrfTokenRepository)
4.1RC2
@jgoldhammer Thanks for the report!
Hi Rob (@rwinch) and Joe (@jgrandja),
I was able to dive deeper into the topic and my created issue and proposed solution causes a bug in our application. Why?
HttpOnly cookies are important in general for web security for protecting sensitive values in browsers which should not be stolen by javascript injection like xsss, but httponly cookies cannot be read from javascript, so our application was not able to read the csrf token from the cookie.
How does our scenario looks like?
So the csrf cookie cannot be protected in this case which makes are application less secure...
I think, the general mechanism for CSRF and single page applications (only using Spring MVC for building up the rest service) should be adressed in future releases for Spring Security. What do you think?
Thanks,
Jens
@jgoldhammer Thanks for the feedback.
I had given this some thought already. You are right that JavaScript cannot access the cookie. This might be desirable in the case where an application populates the token manually and simply wants to store the CSRF in a cookie rather than session.
If an application needs JavaScript to read the cookie, then they can set httpOnly to false explicitly. This would ensure that JavaScript can still read the CSRF token.
The distinction here is that the default is more secure. If users want, they can take specific measures to open it up to JavaScript.
Does this make sense?
Hi Rob,
you are right- it is up to the usecase. The user of Spring Security can decide it- in my eyes, it would make sense that users are able to activate a simple csrf config in spring security and the csrf token is populated in a http resonse header. I would like to see a spring security headerwriter to populate the current csrf token in a http resonse header, so that users don´t have to take care of that implementation. Would it make sense to you?
Thanks,
Jens
@jgoldhammer I'm not sure it makes sense. Would you really want the token added to every response? I don't think that most users would like this. Instead, I think it makes more sense to create an endpoint that exposes the CSRF token. In many instances I see this combined with the user endpoint to reduce the number of requests.
Hi folks,
What's the primary Use-Case of _CookieCsrfTokenRepository_? Based on https://github.com/spring-projects/spring-security/pull/3805/commits/b3192787f516211103eb5855138be9497536707b#diff-1b867fd67a4cc7cb6ac6f86b970cf5d5R381 and the description in the api-documentation I would assume it's the go-to solution tailored specificly for AngularJS (or with some configuration other JavaScript code).
Thus, I would argue the "httpOnly" flag set to true is not a sane default — since the very purpose of this _CookieCsrfTokenRepository_ is to enable JavaScript to read the CSRF-token (via cookie).
At least an additional hint in the class-documentation would be useful, e.g.: "if you intend to use this CSRF-Configuration with JavaScript, make sure to set CookieHttpOnly to false, but be aware of security-implications".
@zauberpony Thanks for your feedback. I have replied below.
What's the primary Use-Case of CookieCsrfTokenRepository?
There are two use-cases. The first is for users who do not want to leverage the HTTP Session for persisting the CSRF token. This is not as secure as using a session, but it may be "secure enough" for some applications.
The second use-case is for working with JavaScript frameworks like AngularJS. It so happens that most of the defaults align with AngularJS as this makes life easier for users. In 4.1.1 we even provide a static factory method to make creating it with httpOnlyFalse easier.
Thus, I would argue the "httpOnly" flag set to true is not a sane default
Due to the fact that it is not just for JavaScript frameworks & because a security framework should be secure by default, we need to keep httpOnly flag set to true.
At least an additional hint in the class-documentation
Agreed. We have already addressed this in 4.1.1 with #3865. We even created a static factory method to make life easier for users. You can find some of these changes in the SNAPSHOT version of the reference documentation
Most helpful comment
@zauberpony Thanks for your feedback. I have replied below.
There are two use-cases. The first is for users who do not want to leverage the HTTP Session for persisting the CSRF token. This is not as secure as using a session, but it may be "secure enough" for some applications.
The second use-case is for working with JavaScript frameworks like AngularJS. It so happens that most of the defaults align with AngularJS as this makes life easier for users. In 4.1.1 we even provide a static factory method to make creating it with httpOnlyFalse easier.
Due to the fact that it is not just for JavaScript frameworks & because a security framework should be secure by default, we need to keep httpOnly flag set to true.
Agreed. We have already addressed this in 4.1.1 with #3865. We even created a static factory method to make life easier for users. You can find some of these changes in the SNAPSHOT version of the reference documentation