diff --git a/website/api/controllers/redirect-vanta-authorization-request.js b/website/api/controllers/redirect-vanta-authorization-request.js index 82e380342f..8fd85daac0 100644 --- a/website/api/controllers/redirect-vanta-authorization-request.js +++ b/website/api/controllers/redirect-vanta-authorization-request.js @@ -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});