yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.23k stars 6.91k forks source link

Unable to verify data submission - csrf token out of date due to additional request forcing a refresh #19351

Closed developedsoftware closed 2 years ago

developedsoftware commented 2 years ago

We are using yii/web/DbSession to manage our sessions. We are getting hundreds of "Unable to verify your data submission" since updating the framework to the latest version.

If we disable CSRF checks - the problem dissapears (obviously). If we set enableCsrfCookie to false in yii/web/Request the issue also dissapears once we clear our cookies.

From what I can tell the cookie value is getting the serialised output from the session table appeneded to the end of it.

At first I thought it was our implementation of the framework but after several hours of trying to pin it down I cannot seem to see anywhere in our code whereby we would alter this.

So now I am thinking it may be a framework issue. But please forgive me because I am not totally sure how I can explain how to replicate the issue.

Does anybody have any ideas that could start me off on the road of discovery?

Screenshot 2022-04-13 at 11 17 08 Screenshot 2022-04-13 at 11 17 03
developedsoftware commented 2 years ago

@proditis the favico request IS after the get request. So the login form was rendered with a csrf token as a hidden input. The favicon request came later, causing a request to the login page again. Which meant the form input on the original login page is out of date and causes the 400 error. Removing the hidden field from the form will solve it as the cookie value gets updated. The cause of it is an outdated form value which DOES not get updated if a second request is made after the page is loaded.

developedsoftware commented 2 years ago

In fact, isn’t the solution to simply remove the hidden csrf input from forms if cookie validation is enabled and the cookie is secure ? Surely the cookie value is good enough to rely on without needing to submit the csrf token as a hidden form field ?

bizley commented 2 years ago

Looking through the issue again after some time I can see that while maybe we did not find the perfect solution for the problem for sure we can agree that all parallel calls that might change the CSRF token should be prepared to not do that, and that is "by the developer". So I'm closing this as it is, and if anything new comes up please write here so we can re-open.

My6UoT9 commented 2 years ago

In fact, isn’t the solution to simply remove the hidden csrf input from forms if cookie validation is enabled and the cookie is secure ? Surely the cookie value is good enough to rely on without needing to submit the csrf token as a hidden form field ?

No the cookie is not enough, it is explicitly about the issue of an authenticated user.

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application. https://owasp.org/www-community/attacks/csrf

PS: Don't want to reopen this issue, just clear up misunderstanding.

developedsoftware commented 2 years ago

Its nothing to do with the authentication of a user? Its to do with the csrf check failing (authenticated or not)

If a cookie is marked as httpOnly and Secure then surely not including the csrf token in the form is WAY more secure.

httpOnly and Secure means the cookie cannot be read by javascript. If the token also isnt in the dom then it cannot be read by javascript either. So if these 2 flags are set then surely the cookie is enough to validate csrf and the form input isnt even needed?

I have got round the issue, so this doesnt need to be re-opened. But not making any further requests after the login page is a workaround and not a solution.

My6UoT9 commented 2 years ago

Its nothing to do with the authentication of a user? Its to do with the csrf check failing (authenticated or not)

If a cookie is marked as httpOnly and Secure then surely not including the csrf token in the form is WAY more secure.

httpOnly and Secure means the cookie cannot be read by javascript. If the token also isnt in the dom then it cannot be read by javascript either. So if these 2 flags are set then surely the cookie is enough to validate csrf and the form input isnt even needed?

I have got round the issue, so this doesnt need to be re-opened. But not making any further requests after the login page is a workaround and not a solution.

I think u do not understand the problem. A user has a valid cookie, is authenticated.

Now a 3.party page, makes u click a link which contains post data - e.g. a form, and it links to your yii2 setup. Now your yii2, sees a valid cookie, and valid post data - and will happily do whatever it is told.

That is where the csrf token comes in, for each form u create a token, and then u can validate that u have made this form and not someone else.

developedsoftware commented 2 years ago

OK, so if you solely rely on the cookie then I guess it can still be exploited?

neoacevedo commented 2 years ago

I am getting randomly this error. Sometimes, when I try to login, sometimes with a simple post click from an a element for a delete, but this last one is very specific when I try to call manually the delete action via fetch/javascript, passing via body and/or header the csrf token but not else if I click a link which runs the default yii2 event.