diff --git a/core/frontend/apps/private-blogging/lib/middleware.js b/core/frontend/apps/private-blogging/lib/middleware.js index 0382d672d8..75d4c60a99 100644 --- a/core/frontend/apps/private-blogging/lib/middleware.js +++ b/core/frontend/apps/private-blogging/lib/middleware.js @@ -1,5 +1,4 @@ const fs = require('fs-extra'); -const url = require('url'); const session = require('cookie-session'); const crypto = require('crypto'); const path = require('path'); @@ -25,7 +24,12 @@ function verifySessionHash(salt, hash) { function getRedirectUrl(query) { try { const redirect = decodeURIComponent(query.r || '/'); - return url.parse(redirect).pathname; + const pathname = new URL(redirect, config.get('url')).pathname; + + const base = new URL(config.get('url')); + const target = new URL(pathname, config.get('url')); + // Make sure we don't redirect outside of the instance + return target.host === base.host ? pathname : '/'; } catch (e) { return '/'; } diff --git a/test/unit/apps/private-blogging/middleware_spec.js b/test/unit/apps/private-blogging/middleware_spec.js index be2c61f3d0..e3a05247a4 100644 --- a/test/unit/apps/private-blogging/middleware_spec.js +++ b/test/unit/apps/private-blogging/middleware_spec.js @@ -267,6 +267,32 @@ describe('Private Blogging', function () { res.redirect.args[0][0].should.be.equal('/'); }); + it('doLoginToPrivateSite should redirect to the relative path if r param is there', function () { + req.body = {password: 'rightpassword'}; + req.session = {}; + req.query = { + r: encodeURIComponent('/test') + }; + res.redirect = sinon.spy(); + + privateBlogging.doLoginToPrivateSite(req, res, next); + res.redirect.called.should.be.true(); + res.redirect.args[0][0].should.be.equal('/test'); + }); + + it('doLoginToPrivateSite should redirect to "/" if r param is redirecting to another domain than the current instance', function () { + req.body = {password: 'rightpassword'}; + req.session = {}; + req.query = { + r: encodeURIComponent('http://britney.com//example.com') + }; + res.redirect = sinon.spy(); + + privateBlogging.doLoginToPrivateSite(req, res, next); + res.redirect.called.should.be.true(); + res.redirect.args[0][0].should.be.equal('/'); + }); + describe('Bad Password', function () { beforeEach(function () { req.session = {