Skip to content

fix(security): introspect auth bypass, backchannel SSRF, session rollover#606

Merged
lakhansamani merged 1 commit intomainfrom
security/introspect-bcl-session-fixes
Apr 12, 2026
Merged

fix(security): introspect auth bypass, backchannel SSRF, session rollover#606
lakhansamani merged 1 commit intomainfrom
security/introspect-bcl-session-fixes

Conversation

@lakhansamani
Copy link
Copy Markdown
Contributor

Summary

  • Introspect endpoint client_secret bypass (Medium): The /oauth/introspect handler previously used clientSecret != "" && h.Config.ClientSecret != "" — both sides had to be non-empty, so omitting the secret bypassed authentication entirely. Now requires client_secret whenever the server has one configured, using crypto/subtle.ConstantTimeCompare for timing-safe comparison.

  • Backchannel logout SSRF (Low): Replaced plain http.Client{} with validators.SafeHTTPClient() which resolves DNS upfront, pins the IP, and rejects private/loopback addresses. Aligns with defense-in-depth posture already applied to test_endpoint and webhooks.

  • Session rollover fire-and-forget (Low): Wrapped goroutine with error logging so failed old-session deletions are visible in logs instead of silently discarded.

  • Duplicate test fix: Removed copy-paste duplicate RFC7636_plain_code_challenge_method_is_accepted test that actually tested unsupported method with wrong assertion — was failing on main.

Security review

Reviewed by security-engineer agent. All fixes verified correct. The agent flagged token.go:248 (clientSecret != "") as a potential similar bypass, but on inspection this is correct RFC 6749/7636 behavior — public clients use PKCE without a secret, and when no PKCE is used, the secret is already required (lines 239-245).

Test plan

  • TestIntrospectMissingClientSecretRejectsWhenConfigured — new test, verifies secret is required when configured
  • TestIntrospectWrongClientSecretRejects — new test, verifies wrong secret is rejected
  • TestIntrospectActiveAccessToken — updated to include secret, passes
  • TestIntrospectActiveIDToken — updated to include secret, passes
  • TestBackchannelLogoutRejectsLocalhostSSRF — new test, verifies SSRF protection is wired in
  • TestBackchannelLogoutJWTClaims — verifies JWT claim structure per OIDC BCL 1.0 §2.4
  • Full integration suite passes (TEST_DBS=sqlite, 44s)

…over logging

- Introspect endpoint: require client_secret when server has one configured.
  Previously the AND condition allowed callers to skip auth by omitting the
  secret. Now uses crypto/subtle.ConstantTimeCompare for timing-safe comparison.

- Backchannel logout: replace plain http.Client with SafeHTTPClient to block
  SSRF against private/loopback addresses via DNS-pinning validation.

- Session rollover: log failed old-session deletion instead of silently
  discarding the error from the fire-and-forget goroutine.

- Remove duplicate copy-paste test (RFC7636 plain method) that was always
  failing on main.
@lakhansamani lakhansamani merged commit 1726717 into main Apr 12, 2026
@lakhansamani lakhansamani deleted the security/introspect-bcl-session-fixes branch April 12, 2026 05:56
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