diff --git a/src/config.js b/src/config.js index 9b0771f..f91ef5e 100644 --- a/src/config.js +++ b/src/config.js @@ -17,7 +17,8 @@ module.exports = { api_base: jsonConfig.api_base, http: { base_url: jsonConfig.http.base_url, - port: jsonConfig.http.port + port: jsonConfig.http.port, + allowed_redirection_suffixes: Array.isArray(jsonConfig.http.allowed_redirection_suffixes) ? jsonConfig.http.allowed_redirection_suffixes : ['pretendo.network'] }, github: { graphql_token: jsonConfig.github.graphql_token diff --git a/src/middleware/redirect.js b/src/middleware/redirect.js index 6aa9de5..cd6b7b1 100644 --- a/src/middleware/redirect.js +++ b/src/middleware/redirect.js @@ -1,14 +1,31 @@ +const config = require('../config'); + +function isValidRedirect(redirect) { + if (!redirect) return false; + if (redirect.startsWith('/')) return true; + if (redirect.startsWith('http://') || redirect.startsWith('https://')) { + try { + const url = new URL(redirect); + return config.http.valid_redirection_domains.some(domain => url.hostname.endsWith(domain)); + } catch (ignored) { + return false; + } + } + + return false; +} + async function redirectMiddleware(request, response, next) { if (request.path.startsWith('/account/logout')) { return next(); } - if (request.method === 'POST') { - request.redirect = request.body.redirect?.startsWith('/') ? request.body.redirect : null; + if (request.method === 'POST' && request.body) { + request.redirect = isValidRedirect(request.body.redirect) ? request.body.redirect : null; } if (request.query.redirect) { - response.locals.redirect = request.query.redirect?.startsWith('/') ? request.query.redirect : null; + response.locals.redirect = isValidRedirect(request.query.redirect) ? request.query.redirect : null; } return next();