fix(oidc): close open redirect, scope leak, client auth, dead code (BUNYIP-74) #230

Merged
Claude-Run merged 1 commit from fix/bunyip-74-oidc-handlers into main 2026-06-26 01:22:53 +02:00
Member

Harden the OIDC endpoint handlers in crates/bunyip-oidc/src/handlers/oidc.rs against a cluster of spec violations and remove dead code.

  • RP-logout open redirect: only honour a post_logout_redirect_uri that is registered for some client (runtime query against oauth_clients); anything else falls back to "/". The state parameter is now echoed back on the redirect when present, per the OIDC RP-Initiated Logout spec.
  • Userinfo scope leak: gate the email / email_verified / membership_status / has_member_access claims on the email scope, mirroring mint_id_token so userinfo never discloses more than the granted scopes.
  • Empty scope intersection: return invalid_scope instead of issuing a code when none of the requested scopes survive the intersection with the client's allowed set (RFC 6749).
  • Revocation endpoint: authenticate the client (extract_client_credentials + authenticate_client) before acting, and scope the revocation to the authenticating client so a client cannot revoke another client's tokens (RFC 7009).
  • do_revoke now uses the shared sha256_bytes helper instead of a hand-rolled SHA-256, via runtime queries so the added client_id predicate needs no .sqlx cache regen.
  • Corrected the revoke docstring: there is no access-token blocklist; short-lived stateless JWTs are left to expire.
  • Discovery no longer advertises private_key_jwt, which authenticate_client does not support.
  • Backchannel logout reuses a single reqwest client built once at startup and injected via app state; the builder error now fails fast instead of being swallowed by unwrap_or_default.
  • Removed dead oidc_unauthorized(), the never-read LogoutQuery.id_token_hint field, the unused _pool parameter in authorize, and the unused data-encoding / hex / url deps from crates/bunyip-oidc/Cargo.toml.

#BUNYIP-74

Harden the OIDC endpoint handlers in crates/bunyip-oidc/src/handlers/oidc.rs against a cluster of spec violations and remove dead code. - RP-logout open redirect: only honour a post_logout_redirect_uri that is registered for some client (runtime query against oauth_clients); anything else falls back to "/". The state parameter is now echoed back on the redirect when present, per the OIDC RP-Initiated Logout spec. - Userinfo scope leak: gate the email / email_verified / membership_status / has_member_access claims on the email scope, mirroring mint_id_token so userinfo never discloses more than the granted scopes. - Empty scope intersection: return invalid_scope instead of issuing a code when none of the requested scopes survive the intersection with the client's allowed set (RFC 6749). - Revocation endpoint: authenticate the client (extract_client_credentials + authenticate_client) before acting, and scope the revocation to the authenticating client so a client cannot revoke another client's tokens (RFC 7009). - do_revoke now uses the shared sha256_bytes helper instead of a hand-rolled SHA-256, via runtime queries so the added client_id predicate needs no .sqlx cache regen. - Corrected the revoke docstring: there is no access-token blocklist; short-lived stateless JWTs are left to expire. - Discovery no longer advertises private_key_jwt, which authenticate_client does not support. - Backchannel logout reuses a single reqwest client built once at startup and injected via app state; the builder error now fails fast instead of being swallowed by unwrap_or_default. - Removed dead oidc_unauthorized(), the never-read LogoutQuery.id_token_hint field, the unused _pool parameter in authorize, and the unused data-encoding / hex / url deps from crates/bunyip-oidc/Cargo.toml. #BUNYIP-74
fix(oidc): close open redirect, scope leak, client auth, dead code (BUNYIP-74)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 55s
Check / fmt + clippy + build + tests (pull_request) Successful in 5m40s
Create release / Create release from merged PR (pull_request) Has been skipped
fba7df7cce
Harden the OIDC endpoint handlers in crates/bunyip-oidc/src/handlers/oidc.rs against a cluster of spec violations and remove dead code.

- RP-logout open redirect: only honour a post_logout_redirect_uri that is registered for some client (runtime query against oauth_clients); anything else falls back to "/". The state parameter is now echoed back on the redirect when present, per the OIDC RP-Initiated Logout spec.
- Userinfo scope leak: gate the email / email_verified / membership_status / has_member_access claims on the email scope, mirroring mint_id_token so userinfo never discloses more than the granted scopes.
- Empty scope intersection: return invalid_scope instead of issuing a code when none of the requested scopes survive the intersection with the client's allowed set (RFC 6749).
- Revocation endpoint: authenticate the client (extract_client_credentials + authenticate_client) before acting, and scope the revocation to the authenticating client so a client cannot revoke another client's tokens (RFC 7009).
- do_revoke now uses the shared sha256_bytes helper instead of a hand-rolled SHA-256, via runtime queries so the added client_id predicate needs no .sqlx cache regen.
- Corrected the revoke docstring: there is no access-token blocklist; short-lived stateless JWTs are left to expire.
- Discovery no longer advertises private_key_jwt, which authenticate_client does not support.
- Backchannel logout reuses a single reqwest client built once at startup and injected via app state; the builder error now fails fast instead of being swallowed by unwrap_or_default.
- Removed dead oidc_unauthorized(), the never-read LogoutQuery.id_token_hint field, the unused _pool parameter in authorize, and the unused data-encoding / hex / url deps from crates/bunyip-oidc/Cargo.toml.

#BUNYIP-74
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!230
No description provided.