Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSRF token expires during login

I'm working on Spring web application and I need to avoid problem with expire csrf token on login page, because if user is waiting too long and try to login only one way to resolve problem with csrf is to reload page and try to login again. But it's not user friendly and I want to avoid this situation.

First question: Is it possible in general(by spring security 3.2.4)? Without disable csrf.

I tried to use security="none" for login page and spring seciruty "login_check", but it's not working, i got infinity redirect or I got error that no mapping for url "myhost/login_check".

Second question: How can i do it?

like image 951
Vartlok Avatar asked Dec 16 '14 09:12

Vartlok


1 Answers

Recommended solution

I would say that you should not disable csrf tokens on a production site. You may make session (and thus the csrf token) last longer (but it usually should not last longer than a day, especially for not-logged-in users as it is a DOS vector), but the real solution may be to automatically refresh the login page when the csrf token expires. You may use a

<META HTTP-EQUIV="REFRESH" CONTENT="csrf_timeout_in_seconds">

in your login page header. If the user lets the login page sit for hours, it should not bother him that the page got refreshed.

Second solution

A possible solution which does not require you to actually store sessions but allows for infinite timeout is that you can generate your csrf tokens with hashing from the session id and a server-side secret:

csrf = hash(sessionid+secret)

Note however that you need to really dig and override spring-security internal mechanisms, namely:

  • re-creating anonymous sessions on the fly if a request arrives and no such session exists
  • re-creating the csrf token on the fly from the session id

And choose a very secure hashing algorithm, preferably sha-512.

Third solution

You could have a small javascript that calls a no-op page on your server regularly (just before the session timeout), thus extending your session. This results in infinite session timeout only if the browser is on all the time, so the DOS aspect is mitigated.

Ok, one last solution

You can alter the CSRF token checking code, and disable it for the login page. This is actually synonymous with the second solution, but is specific for the login page, not generally for all anonymous sessions.

You can do this e.g. by setting a custom RequestMatcher in HttpSecurity:

http.csrf().requireCsrfProtectionMatcher(new MyCsrfRequestMatcher());
...
class MyCsrfRequestMatcher implements RequestMatcher {
    @Override
    public boolean matches(HttpServletRequest request) {
        return !request.getServletPath().equals("/login");
    }
}
like image 158
P.Péter Avatar answered Sep 19 '22 19:09

P.Péter