Skip to content

Reject discovered IdP endpoints with a non-HTTP scheme - #2427

Open
theredspoon wants to merge 2 commits into
warp-tech:mainfrom
theredspoon:fix/idp-endpoint-scheme-validation
Open

Reject discovered IdP endpoints with a non-HTTP scheme#2427
theredspoon wants to merge 2 commits into
warp-tech:mainfrom
theredspoon:fix/idp-endpoint-scheme-validation

Conversation

@theredspoon

@theredspoon theredspoon commented Aug 14, 2026

Copy link
Copy Markdown

What

Reject any OIDC-discovered endpoint whose scheme isn't http or https.

Why

openidconnect parses discovery endpoints as generic URLs with no scheme constraint, and two of them end up in a client-side navigation (Login.svelte/AuthBar.svelte: location.href = ...). A provider advertising "authorization_endpoint": "javascript:..." gets that assigned to location.href on the gateway's own origin.

This is input hygiene, not a closed vulnerability: javascript:/data: are never legitimate values here, so rejecting anything outside http/https is a three-line check with no behavior change for any real deployment.

Where

Checked once in discover_metadata() (warpgate-sso/src/metadata.rs), the single choke point every consumer of discovery metadata goes through, before the document is cached. A rejected endpoint is a hard error (SsoError::UnsupportedEndpointScheme), matching how other discovery/config problems already fail in this code. Login.svelte/AuthBar.svelte also get a navigateToExternalUrl() helper as a second line of defense.

Tests

New unit tests in warpgate-sso/src/metadata.rs cover valid http/https documents and rejection of javascript:/data:/file: on each affected endpoint. cargo test -p warpgate-sso, clippy, and biome check all pass.

OIDC discovery metadata is parsed by `openidconnect` as generic URLs with
no constraint on the scheme, so a compromised or maliciously configured
provider can advertise e.g. `javascript:...` as its authorization_endpoint
or end_session_endpoint. Both of those are returned to the browser by
`GET /sso/providers/:name/start` and `GET /sso/logout` and assigned to
`location.href`, which would run script on the gateway's own origin.

Validate in `discover_metadata`, the single point every consumer of
discovery metadata goes through, and before the document is cached.
Anything other than http/https is a hard `SsoError`, matching how the
surrounding code already treats other discovery and SSO config problems.

Also route the two frontend call sites through a `navigateToExternalUrl`
helper that re-checks the scheme, as defence in depth.
@Eugeny

Eugeny commented Aug 14, 2026

Copy link
Copy Markdown
Member

Is there an actual case where this can happen? A hostile OIDC provider is not really a part of the threat model - it doesn't need to bother with running javascript when it can just issues an admin login.

(no LLM replies please)

@theredspoon

Copy link
Copy Markdown
Author

Hey @Eugeny, human here.

What happened here is that once a security finding came up in one of my LLM reviews on #2397, I figured I would point a security sweep at the codebase and share whatever came up, however minimal in it. Better disclose than not. And to be honest, I wasn't investigating deeply, just leaning on quantity as its own quality.

Of course on the face of it if an OIDC provider is compromised, they can do a lot worse than a javascript injection.

I would consider this PR more hygiene than a gap-closer. I've updated the PR body accordingly.

Related to that, would you be open to me opening a PR to add more context to SECURITY.md to better assist LLMs? I wouldn't want anyone's time wasted with findings you wouldn't advance due to them falling outside of the declared scope. I think the following could help:

  - Privileged-by-design actors turning hostile are out of scope, regardless of how many tiers exist.
  - Hardening suggestions are welcome; their absence isn't itself a vulnerability unless independently reachable.
  - Malicious transitive dependencies are only in-scope with a confirmed exploit path, not just a bad advisory.
  - A trusted IdP's own authenticated users acting maliciously is between them and the IdP, not Warpgate.
  - Only code that shipped in a tagged release needs a formal advisory.
  - Judge severity against the most direct alternative attack the same actor already has.

…heme-validation

# Conflicts:
#	warpgate-web/src/common/helpers.ts
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