Skip to content

Fix percent-decoding for custom OAuth provider identifiers issues #2541 #2554

Open
big1231945 wants to merge 2 commits into
supabase:masterfrom
big1231945:master
Open

Fix percent-decoding for custom OAuth provider identifiers issues #2541 #2554
big1231945 wants to merge 2 commits into
supabase:masterfrom
big1231945:master

Conversation

@big1231945
Copy link
Copy Markdown

@big1231945 big1231945 commented May 29, 2026

What kind of change does this PR introduce?

Bug fix.

What is the current behavior?

#2541
Managing a custom OAuth/OIDC provider from the dashboard fails. Fetching, updating, or deleting a provider returns:

Failed to delete custom OAuth provider: identifier must start with 'custom:' prefix, e.g. 'custom:custom%3Aline'

Root cause: the admin GET / PUT / DELETE handlers in internal/api/custom_oauth_admin.go read the provider identifier from the URL path with chi.URLParam and require the custom: prefix. chi routes on (and returns) the raw, still percent-encoded path segment. Browsers encode the : in custom:line as %3A (encodeURIComponent("custom:line") === "custom%3Aline"), so the handler received custom%3Aline, failed the strings.HasPrefix(identifier, "custom:") check, and returned the error above. The %s in the example message (custom:custom%3Aline) is the raw value the server received — confirming the colon arrived encoded and was never decoded.

Creation was unaffected because it reads the identifier from the JSON body, which is not URL-encoded.
Existing tests missed it because they built the path with a literal colon (/admin/custom-providers/custom:foo). With a raw colon Go leaves URL.RawPath empty and chi returns the decoded URL.Path; real browsers send %3A, which populates RawPath and makes chi return the encoded segment.

What is the new behavior?

The path identifier is percent-decoded before the prefix check and the database lookup, so the dashboard can fetch, update, and delete custom providers again. Raw-colon paths keep working and missing-prefix identifiers are still rejected.

Added providerIdentifierFromPath, which url.PathUnescapes the chi.URLParam value before validation, and used it in all three handlers (removing the duplicated inline validation).
Other path parameters in the codebase are UUIDs, which contain no characters a browser would percent-encode, so they are unaffected.
Tests:

TestProviderIdentifierFromPathDecoding — DB-free test driving the real chi routing: asserts custom%3Aline → custom:line, that a raw colon still works, and that a missing prefix is still rejected.
TestGetProviderWithEncodedIdentifier, TestUpdateProviderWithEncodedIdentifier, TestDeleteProviderWithEncodedIdentifier — full-handler integration tests using a custom%3A... path, reproducing the exact dashboard scenario.

Additional context

go build, go vet, and gofmt -l are clean on the touched files. The DB-free routing test passes locally; the DB-backed integration tests run in CI (Postgres was not available in the authoring environment).

claude and others added 2 commits May 29, 2026 22:09
… endpoints

The admin GET/PUT/DELETE custom OAuth provider endpoints read the provider
identifier from the URL path via chi.URLParam and required it to start with
the "custom:" prefix. chi routes on (and returns) the raw, still
percent-encoded path segment, so when a browser encodes the ':' as "%3A"
(encodeURIComponent("custom:line") == "custom%3Aline") the handler saw
"custom%3Aline", failed the strings.HasPrefix(..., "custom:") check, and
returned:

  identifier must start with 'custom:' prefix, e.g. 'custom:custom%3Aline'

This made it impossible to fetch, update, or delete a custom provider from
the dashboard, even though creation (which reads the identifier from the
JSON body) worked fine. The existing tests masked the bug because they
interpolated the identifier into the path with a literal ':' (leaving
URL.RawPath empty, so chi returned the decoded value).

Add providerIdentifierFromPath, which percent-decodes the path parameter
with url.PathUnescape before the prefix check and DB lookup, and use it in
all three handlers. Cover the fix with a DB-free routing test plus
encoded-identifier GET/PUT/DELETE integration tests.

https://claude.ai/code/session_013p2FfvkpPJwAax6aoj8r57
fix(api): decode percent-encoded identifier for custom OAuth provider endpoints
@big1231945 big1231945 requested a review from a team as a code owner May 29, 2026 22:20
@big1231945 big1231945 marked this pull request as draft May 29, 2026 22:30
@big1231945 big1231945 marked this pull request as ready for review May 29, 2026 22:38
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.

2 participants