-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix AJAX login not refreshing CSRF token #13745
base: 5.x
Are you sure you want to change the base?
Fix AJAX login not refreshing CSRF token #13745
Conversation
First quick remark. The eventsubcriber should probably better live in https://github.com/mautic/mautic/blob/5.x/app/bundles/CoreBundle/EventListener/RequestSubscriber.php instead of Coresubscriber. In that place there is already code for isAjaxPost and isSecurePath to leverage to not set for api calls, or add something similar there. |
I pushed a fix, apparently forgot to remove some usages in GrapesJS. Also removed 2 definitions from the GrapesJS Demo folder. Not sure if it relied on those specific values, couldn't find anything at least. |
I followed the issue steps mentioned at #13527 and by following "The quickest" steps I was able to reproduce the issue. But for the real world steps with Forcing garbage collection enabled in index.php. I never saw the AJAX login form but I see the "csrf error". Now when I'm testing the PR again, I feel the sorting button is not functioning properly and doesn't work at my end when I click on the header titles. After I'm using ddev at my local for setting up Mautic. |
@abhisekmazumdar Hmm, did you check the "remember me" when logging in? That may bypass the need to login manually when your session expires, but will still invalidate the csrf token so you'd still see that error without this PR. |
@abhisekmazumdar as for the seemingly broken JS, any errors in console that you can see or something else? I'll try and reproduce the issue locally as well. |
Oh, I forgot to mention that. I don't see any console error. |
gitpod is acting up and doesn't want to start properly, but if I try it locally I don't see any malformed sorted lists. To be fair, it doesn't seem to sort anything at all. even when I just spin up 5.1 without this PR sorting by name or email or anything does not change the order in any way shape or form so it is possible it's broken in some way in 5.1 itself. Try sorting emails instead, that one still seems to work as it should in 5.1 |
@abhisekmazumdar There is apparently a redesign in 5.x, that isn't in 5.1. I'm assuming your before is on 5.x, this PR is against 5.1 as it is a bugfix. That's why it looks different. When you sort the list on 5.1, does the sorting work or does nothing happen? |
@abhisekmazumdar disregard all the things, the 5.1 branch is not an RC it's a leftover from a long time ago. So I definitely made my PR against the wrong branch, I'll rebase and update. |
…always have up to date value
81e71d1
to
86c77e7
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## 5.x #13745 +/- ##
=========================================
Coverage 61.62% 61.63%
- Complexity 34145 34148 +3
=========================================
Files 2245 2245
Lines 102077 102090 +13
=========================================
+ Hits 62909 62919 +10
- Misses 39168 39171 +3
|
I can confirm now that I don't see |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have conducted functional testing locally and was able to confirm that I do not see any CSRF errors.
I have reviewed the code and do not see any unexpected issues.
) { | ||
} | ||
|
||
public static function getSubscribedEvents(): array | ||
{ | ||
return [ | ||
KernelEvents::REQUEST => ['validateCsrfTokenForAjaxPost', 0], | ||
KernelEvents::REQUEST => ['validateCsrfTokenForAjaxPost', 0], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nitpicking an extra space here.
Description:
The current approach is to set the CSRF token in the HTML, which means that:
This PR instead sets the CSRF token in a cookie, and the JS reads the value of that cookie and sets it as a header before making an AJAX POST call. We never read the cookie itself to actually validate any calls server side, as that would defeat the purpose of CSRF protection.
This ensures that the CSRF token available to the JS (in any tab) is always up to date as any request to the server ensures a correct value in the cookie (including a login request).
Important:
I'm not sure I put the cookie creation in the right spot. Ideally it only sets that cookie for HTML and Ajax requests, not for API calls but I couldn't find a decent spot that met those criteria.Tests still need updating.I haven't even fully tested every case myself manually.Haven't found any edge cases so far, but if anyone can think of any please add them. I'm worried about generating a session for, say, leads being tracked. As far as I could find, all those tracking pages are public, but perhaps there is an exception somewhere.
Another option could be to use the INTERACTIVE_LOGIN event, which only fires upon successful login and to check for /s/ there as well which should limit it to only UI logins. I believe it even fires for remember me cookie logins. Unless there is a usecase where the csrf token has been invalidated somehow and needs refreshing but that event doesn't fire, then it would break not until a page refresh but until you log out and in, which seems a worse "worst case" than the current one.
Steps to test this PR:
Several ways to test this.
First, I will explain how to reproduce the error, which can be reproduce on any Mautic instance currently in the wild.
The quickest:
The real world scenario (unpredictable due to garbage collection chance)
Forcing garbage collection to force the real world scenario to occur sooner
To test this PR,open this PR on Gitpod or pull down for testing locally (see docs on testing PRs here) and try any of the scenarios above. They should no longer occur.