Fix open redirect in Vanta authorization redirect endpoint (#49077)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** NA (found via Aikido SAST triage) ## What changed `GET /redirect-vanta-authorization-request` is a public, unauthenticated endpoint that set signed cookies and then redirected the browser to the caller-supplied `vantaAuthorizationRequestURL` with no validation. Because the redirect target came straight from a query parameter, the endpoint could be abused as an open redirect: an attacker could craft a `https://fleetdm.com/redirect-vanta-authorization-request?...&vantaAuthorizationRequestURL=https://evil.example.com` link that bounces a victim to an arbitrary domain (phishing). The only prior gate was a `VantaConnection.findOne({vantaSourceId})` lookup, which does not bind the source ID to the redirect target and is satisfiable by anyone who has ever initiated a Vanta connection. This adds a host/scheme allowlist before redirecting. The legitimate destination is always `https://app.vanta.com/oauth/authorize?...` (constructed server-side in `create-vanta-authorization-request.js`), so the endpoint now only redirects when the parsed URL is `https:` and its host is `app.vanta.com`; otherwise it returns `badRequest`. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] QA'd all new/changed functionality manually Legitimate flow (redirect target `https://app.vanta.com/...`) still redirects as before; a target on any other host or a non-`https` scheme now returns `badRequest` instead of redirecting. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved safety for authorization redirects by validating the destination before sending users onward. * Redirects now only proceed when the target uses a secure connection and the approved site. * Invalid or malformed redirect links now return a clear bad-request response instead of continuing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -36,6 +36,10 @@ module.exports = {
|
||||
description: 'No Vanta connection could be found using the provided vantaSourceId',
|
||||
responseType: 'badRequest'
|
||||
},
|
||||
invalidVantaAuthorizationRequestURL: {
|
||||
description: 'The provided vantaAuthorizationRequestURL is not a valid Vanta authorization URL.',
|
||||
responseType: 'badRequest'
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -49,6 +53,18 @@ module.exports = {
|
||||
throw 'noMatchingVantaConnection';
|
||||
}
|
||||
|
||||
// Since this is a public endpoint and the destination is caller-supplied, only allow redirecting
|
||||
// to Vanta's authorization host. This prevents the endpoint from being abused as an open redirect.
|
||||
let parsedVantaAuthorizationRequestURL;
|
||||
try {
|
||||
parsedVantaAuthorizationRequestURL = new URL(vantaAuthorizationRequestURL);
|
||||
} catch (unusedErr) {
|
||||
throw 'invalidVantaAuthorizationRequestURL';
|
||||
}
|
||||
if(parsedVantaAuthorizationRequestURL.protocol !== 'https:' || parsedVantaAuthorizationRequestURL.host !== 'app.vanta.com') {
|
||||
throw 'invalidVantaAuthorizationRequestURL';
|
||||
}
|
||||
|
||||
// Set a 'state' and 'vantaSourceId' cookie on the users browser.
|
||||
this.res.cookie('redirectAfterSetup', redirectAfterSetup, {signed: true});
|
||||
this.res.cookie('state', state, {signed: true});
|
||||
|
||||
Reference in New Issue
Block a user