A user, FerrariFlunker, reports a recurring csrf_detected error when using Discord’s ‘Connect’ functionality in Discourse, despite correct configuration. After extensive debugging, they identify a race condition caused by an update POST request altering the _forum_session cookie after the Discord authorization redirect, leading to CSRF validation failure. The issue is linked to the experimental discourse-chat plugin, which triggers frequent update calls via its PresenceChannel API. The core team, including David Taylor, confirms the issue and implements a fix in Discourse core PR #17108, which resolves the problem for all login types, including Google. The user thanks the community and acknowledges the fix will address the issue without requiring changes to the chat plugin itself.
However after clicking the Authorize button, the user is redirected and met with this message on our forum:
and the error at the top of this topic shows up in the admin logs.
I feel like I’ve read and tried everything to fix this, but it continues to happen. I’ve made sure the Discord Client ID and Secret site settings are correct.
I also made sure the URI was the correct syntax (based on a few related topics I’ve seen):
I think(?) I’ve narrowed it down to an nginx and/or caching issue? Is there supposed to be auth-specific or CSRF-specific stuff defined in discourse.conf that we could be missing?
@merefield, @david, @sam - sorry for the pings but I see your names in a lot of the older csrf related discussions in the past. Do you have any recommendations for this? With Discord auth being an integrated part of discourse, I’m stumped what could be causing this.
I’m still unable to find a pattern. Sometimes it works and connects me correctly, but other times I’m met with the csrf page.
At the moment, I’m most suspect of the last condition check in verified_request?.
Are there any ways to easily check if (valid_request_origin? && any_authenticity_token_valid?) is returning true?
I apologize for the lack of any debug-able information, but I think I was (painfully) able to find (at least what I think) is the issue. I’m still not sure what the fix is, so please read on
The pictures below show a back-to-back instance where I was able to successfully link my account, refreshed/tried it again, and unsuccessfully hit the csrf detected page. I was in an incognito window and did/changed literally nothing between the successful connect and csrf failure. Here’s what I found:
So this first pic shows the _forum_session cookie matching in both 1 and 2 request headers, which resulted in a successful connect.
However after I reloaded the page and tried again (and failed to connect), you can see my search on the left side only shows 1 occurrence of the _forum_session cookie in a request header when it resulted in a failure.
tl;dr: I’m pretty sure the issue stems from the forum_session cookie in the discord?reconnect request header and then the following callback? request header not matching. What would cause them to be different?
Are you getting that error in your own environment? I think either way, this error needs to be looked at by the core team. I’m 2+ weeks into debugging this and still haven’t found an answer
Nice digging! This kind of race condition could certainly cause the issues you’re seeing.
That said, we haven’t had any other reports of this problem, so it sounds like it must be something specific to your site/configuration. What plugins do you have installed on the site? Can you open up the “update” call and see what payload is being sent?
After taking a look at the update calls, I’m thinking you’re right. Here are some screenshots of confirmed ‘update’ requests that caused csrf failures.
I’m seeing a pattern involving cdn What would be misconfigured with that? Let me know if you still need a list of our plugins, I just figured I’d save this reply from +1 picture
with one of our plugins!
After disabling the plugin, further testing, and a successful launch of the related feature to the community… I think I can confidently say we found the culprit.
In hindsight it makes sense why this would be the culprit- the plugin is still marked as experimental and isn’t intended for production sites.
Since I’m 3+ weeks into diagnosing this issue and need to get back on track with our community’s other projects , unfortunately I won’t be able to help find the fix for the discourse-chat plugin.
If someone ends up pushing a fix to the plugin, we’d (most likely ) look into re-enabling the plugin on our site, but for now we need stable associated account Connect functionality
The reason it was fixed after removing the chat plugin is that Chat makes heavy use of this ‘PresenceChannel’ API, and so the issue is far more likely to happen. I don’t think any changes will be required in chat.
Should this fix the same issue with Google Logins? My users on one of my instances where we were testing the chat plugin loved it, but it broke Google logins with the same error as the Discord logins.