I am working on a Spring MVC project. I applied CSRF Token to login form by enabling and using in Spring security. When I go to the login page, I can see that a CSRF Token generated automatically with name _csrf. But when I use ZAP to scan the project, I still get alerts about anti-CSRF Token like this: Anti csrf attack failed

I also tried to remove or edit field _csrf token in form by using develop tool, then login by valid username/password. In that cases, my website always returned 405 error, so I think anti-csrf token worked correctly. Csrf tokens are generated with sessions, so it is impossible for copying csrf token from a session to other session.

I also added _csrf to Anti-CSRF Tokens but it still doesn't work: (you can check image here - Anti-CSRF Tokens)

Do you know the reason why these alerts still exist? And how to fix this?


1 Answer 1


You don't provide quite enough info in your question to verify exactly what is the problem, but I'm reasonably confident that I can guess it anyhow:

Are you doing all of the following:

  1. Generating a unique anti-CSRF token on every GET request to /login?
  2. Tying that unique token to the GET-requesting client (usually with a cookie) such that the server will know what the expected token is for each login POST request?
  3. Verifying that the _csrf token is present on login POST requests and rejecting requests without it?
  4. Verifying that the value of the login POST request's _csrf parameter matches the anti-CSRF token generated for that client's login GET request?

A few guesses at what you might have done wrong:

  1. You're using a static GUID as your anti-CSRF token, and returning it to every user that asks. (This is completely pointless; may as well have no token at all as have a static one.)
  2. You're generating a unique token for each request, but have no way of tying it to a specific user-agent (browser, etc.). Even if you're still verifying that the token you get back is one that was issued recently, an attacker can potentially make a GET request to /login themselves and then CSRF somebody else using the token they received.
  3. You're generating login forms with _csrf hidden tokens, but not requiring them on login POST requests.
  4. You require a _csrf value on POST requests, and you could somehow figure out who that token was issued to, but you're nonetheless accepting tokens issued to other people/user agents. (See the attack scenario laid out two items up.)

Mind you, since the user is (of course) unauthenticated at login, it can be a little tricky to perform CSRF protection correctly on login forms. CSRF protection requires some way of distinguishing users. You don't need to know who they are, yet - that's the job of the login system itself - but you do need to know which anti-CSRF token to expect from them. One way to do this is to tie it to a cookie (sort of like a temporary session cookie), but you need to make sure the attacker can't simply plant their own cookie it its place (for example, by using HSTS so the attacker can never spoof being your server to the victim).

  • Thank you so much for your reply. But I verified issues that you provided, all correctly work. :( Commented May 4, 2019 at 1:58
  • In that case, it's a false positive. You might try checking for updates to ZAP and/or using a different tool, such as Burp Suite. By the way, in the future, it would help if you included the full requests and responses in your screenshots, so we could tell what the supposedly-vulnerable request looks like.
    – CBHacking
    Commented May 4, 2019 at 10:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .