chore: improve sgid state validation #386
Merged
+27
−19
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
The SGID OIDC login flow, while currently safe, is prone to open redirect vulnerabilities related to the
landingUrl
parameter. This URL is passed into thestate
parameter and is derived from query params. There is insufficient validation in between the steps of the login flow, thus is quite prone to open redirect vulnerabilities.This has occurred in kampung-spirit recently and could be partially exploitable in
armoury
.Approach
To mitigate this, we propose the following changes:
Client-side validation: Implement validation of the
landingUrl
on the client side and fallback to a safe URL.Server-side validation: Add server-side validation in both legs of OIDC and always fallback to a safe URL.
Error fallback component: Add validation for the
landingUrl
in the error fallback component.Risks
Testing
Happy SGID flow
https://ogp-starter-kit.vercel.app/
viaenv.SGID_REDIRECT_URI
, so you need to use the callback code manually like so:Happy SGID flow with custom path `/404'
https://starter-5jcverdf5-ogp-tooling.vercel.app/404
after loginHappy email flow
Testing client side validation
With bad callbackUrl
https://starter-5jcverdf5-ogp-tooling.vercel.app/sign-in?callbackUrl=https://evil.com
, the request to sgid loginstate.landingUrl
fallbacks tohttps://starter-5jcverdf5-ogp-tooling.vercel.app/home
Testing server side validation on leg 1
With bad state.landingUrl submitted to
/api/trpc/auth.sgid.login
, responseredirectUrl
has query state{"landingUrl":"https://starter-5jcverdf5-ogp-tooling.vercel.app/home"}
Testing server side validation on leg 2
With bad state.landingUrl submitted to
/api/trpc/auth.sgid.callback
, response jsonTesting error fallback component
redirectUrl
inSgidErrorFallback
is sanitized.