Require HTTPS for the OIDC discovery URL #127
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: LOW
The finding
The security audit confirmed there is no user-driven SSRF in the application: the only outbound
HTTP is Authlib fetching the OIDC discovery document and the token/JWKS endpoints it advertises, and
that URL comes from
CIRCA_OAUTH_SERVER_METADATA_URL— operator configuration, not user input. Agrep for
requests.,urllib, andhttpx.in application code found no direct outbound calls.One residual weakness remains worth closing:
The metadata URL scheme is unvalidated.
http://is accepted. The discovery document is fetchedover whatever scheme is configured, and the endpoints inside it are then trusted for token
exchange and JWKS retrieval. A MITM on a plaintext discovery fetch can redirect token exchange to an
attacker-controlled endpoint.
This is a compromised-or-intercepted-IdP scenario rather than user-driven SSRF, which is why it is
LOW — but the deployment currently defaults to non-HTTPS-enforcing (
CIRCA_ENVIRONMENTdefaults todevelopment), and the IdP is on the same internal network, so plaintext is a realisticconfiguration.
Fix
https://forCIRCA_OAUTH_SERVER_METADATA_URLand refuse to start otherwise, exceptwhen explicitly in development.
variable.
never become user input.
Done when
References
backend/app/config.py:25,48-56backend/app/auth/oauth.py:31Related: #14 (fail fast on insecure configuration), #43 (GenericOAuth2Backend).
Fixed in
4333b5e. CI green.resolved_server_metadata_urlnow refuses a non-https://discovery URL outside development, withan error naming the variable and explaining why.
The reasoning recorded in the code: the discovery document determines the token and JWKS endpoints,
which are then trusted for the code exchange and signature verification. So the transport of this
one request is load-bearing for the entire authentication flow — an attacker on the path can
redirect token exchange to an endpoint they control.
Plaintext is still permitted in development so a local provider on
http://localhostis notblocked. Tested for
http://, uppercaseHTTP://, and a non-HTTP scheme, plus the developmentexemption and the Google fallback being https.