fix(web): accept absolute OIDC issuer URLs in safe_redirect #43

Merged
YousifShkara merged 1 commit from fix/bunyip-web-safe-redirect-allow-issuer into main 2026-06-03 02:24:55 +02:00
Owner

safe_redirect rejected anything that didn't start with a single '/' and
defaulted to /dashboard. That broke the OIDC authorize -> login -> authorize
round-trip end-to-end: bunyip-api's /oauth2/authorize passes the full
authorize URL (https://api.a8n.systems/oauth2/authorize?...) as ?redirect=
when it bounces unauthenticated users to bunyip-web's /login, but
login_get + login_post both ran that through safe_redirect, dropped it on
the floor, and sent the user to /dashboard instead of back to authorize.

Allow absolute URLs whose origin matches Config.oidc_issuer (the BFF
already trusts this for cookie + Bearer purposes; same trust is now
extended to redirect targets). The check is an exact-origin string prefix
match so substring attacks like https://api.a8n.systems.evil.com/... still
fall back to /dashboard. Relative paths starting with '/' (but not '//')
keep their current behaviour; everything else is rejected.

Lock the behaviour with seven unit tests covering: None, relative path,
protocol-relative URL, same-origin absolute URL, foreign-origin absolute
URL, substring attack, and javascript: scheme.

safe_redirect rejected anything that didn't start with a single '/' and defaulted to /dashboard. That broke the OIDC authorize -> login -> authorize round-trip end-to-end: bunyip-api's /oauth2/authorize passes the full authorize URL (https://api.a8n.systems/oauth2/authorize?...) as ?redirect= when it bounces unauthenticated users to bunyip-web's /login, but login_get + login_post both ran that through safe_redirect, dropped it on the floor, and sent the user to /dashboard instead of back to authorize. Allow absolute URLs whose origin matches Config.oidc_issuer (the BFF already trusts this for cookie + Bearer purposes; same trust is now extended to redirect targets). The check is an exact-origin string prefix match so substring attacks like https://api.a8n.systems.evil.com/... still fall back to /dashboard. Relative paths starting with '/' (but not '//') keep their current behaviour; everything else is rejected. Lock the behaviour with seven unit tests covering: None, relative path, protocol-relative URL, same-origin absolute URL, foreign-origin absolute URL, substring attack, and javascript: scheme.
fix(web): accept absolute OIDC issuer URLs in safe_redirect
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / fmt / clippy / build / test (pull_request) Successful in 1m7s
e78b5ca9ee
safe_redirect rejected anything that didn't start with a single '/' and
defaulted to /dashboard. That broke the OIDC authorize -> login -> authorize
round-trip end-to-end: bunyip-api's /oauth2/authorize passes the full
authorize URL (https://api.a8n.systems/oauth2/authorize?...) as ?redirect=
when it bounces unauthenticated users to bunyip-web's /login, but
login_get + login_post both ran that through safe_redirect, dropped it on
the floor, and sent the user to /dashboard instead of back to authorize.

Allow absolute URLs whose origin matches Config.oidc_issuer (the BFF
already trusts this for cookie + Bearer purposes; same trust is now
extended to redirect targets). The check is an exact-origin string prefix
match so substring attacks like https://api.a8n.systems.evil.com/... still
fall back to /dashboard. Relative paths starting with '/' (but not '//')
keep their current behaviour; everything else is rejected.

Lock the behaviour with seven unit tests covering: None, relative path,
protocol-relative URL, same-origin absolute URL, foreign-origin absolute
URL, substring attack, and javascript: scheme.
YousifShkara deleted branch fix/bunyip-web-safe-redirect-allow-issuer 2026-06-03 02:24:56 +02:00
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!43
No description provided.