DiscourseConnect flow no longer functions

Since the update from DiscourseSSO to DiscourseConnect, our SSO integration has stopped working.

We have what is probably an unusual setup, in that there are multiple applications from which SSO can be initiated, rather than a single one. Our software can be installed on-prem or multi-tenanted in the cloud. Each tenant instance of the software includes an SSO link through to our Discourse community. This means that we can initiate the SSO from (for example) tenant1.ourcompany.com and from software.tenant2.com and from something.else.com – nearly a thousand different places.

We don’t have a single central identity provider across all of our tenants; each can use their own IDP solution (Google, O365, AD, Okta, …). Server-side, we have processes and mitigations in place to protect against account take-overs.

Unfortunately, our approach here seems to have stopped working in the most recent Discourse update. (Thanks to this commit.) From a technical perspective, the flow that was working was this:

  • Our backend would, via API, obtain a nonce and SSO details from Discourse
  • Discourse would send a 301 redirect with the SSO payload back to us at a single specific address
  • The server here was configured to ignore the 301 redirect (to avoid nonce errors). Instead, it would parse the Location header, decode the base64 values, get the nonce, generate the SSO payload, sign it with the SSO sercrete and send the user on their merry way to the SSO login URL.

It seems that the nonce has been changed so that it’s attached to the browser session (to protect against CSRF attacks). This means that when we try the flow above, the client browser is missing the _forum_session cookie for the nonce when we send them back to Discourse, and so we get a “nonce expired” message.

Is it possible to make this CSRF protection optional? That is, to have a new setting for enable_secure_nonce which we can set to false?

As it stands, most of our customers are locked out of our forum, and we’re looking at having to get them all to set up passwords, and losing our ability to track forum notifications in our app – so we’ll see a downturn in engagement. :frowning:

2 Likes

Yes traditionally we have always supported site settings for cases like this. We will probably make it a hidden setting cause it is very hard to explain, but I do support it for outlier cases like yours. We can then enable it on your instance.

@david will have a look at this.

7 Likes

It’s now possible to disable the protection via the rails console by running

SiteSetting.discourse_connect_csrf_protection=false

You should only do this if you understand and accept the risks it introduces. For anyone hosted by discourse.org, please get in touch and we can flip the setting for you.

(cc @rysher who had a similar request)

9 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.