Skip to content

fix(oidc): don't mutate shared config on Facebook id_token login - #2816

Open
suvvvv wants to merge 1 commit into
supabase:masterfrom
suvvvv:fix/facebook-oidc-config-race
Open

suvvvv wants to merge 1 commit into
supabase:masterfrom
suvvvv:fix/facebook-oidc-config-race

Conversation

@suvvvv

@suvvvv suvvvv commented Sep 16, 2026

Copy link
Copy Markdown

What

In getProvider, the Facebook branch aliases the shared configuration and mutates it:

case p.Provider == FacebookProvider || p.Issuer == provider.IssuerFacebook:
    cfg = &config.External.Facebook // pointer INTO the process-wide *conf.GlobalConfiguration
    cfg.SkipNonceCheck = true        // writes shared state on every request

config is the long-lived *conf.GlobalConfiguration shared across all requests, so cfg aliases config.External.Facebook and this writes shared state on every Facebook id_token login. Concurrent Facebook logins — and any concurrent reader of config.External.Facebook — race on this write (go test -race territory). The written value is always true, so the practical harm is limited, but it is a real data race and an unexpected persistent mutation of shared config.

The custom: and default branches already avoid this by building a local conf.OAuthProviderConfiguration value.

Fix

Copy the provider config into a local value and set SkipNonceCheck on the copy, leaving the shared config untouched.

Testing

Added TestGetProviderFacebookDoesNotMutateSharedConfig: with Facebook disabled, getProvider returns before any OIDC discovery (no network), and the test asserts config.External.Facebook.SkipNonceCheck remains false after the call — it is true on the old aliasing code. go vet, gofmt, and the OIDC test suite pass.

The Facebook branch of getProvider aliased config.External.Facebook — a
field of the long-lived, process-wide *conf.GlobalConfiguration shared
across all requests — and wrote SkipNonceCheck on it on every Facebook
id_token login. Concurrent Facebook logins (and any concurrent reader of
that config) race on this write.

Copy the provider config into a local value and override SkipNonceCheck on
the copy, matching what the custom/default branches already do. Adds a test
asserting the shared config's SkipNonceCheck is not mutated.
@suvvvv
suvvvv requested a review from a team as a code owner September 16, 2026 13:19

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant