0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

🔒 Fixed open redirect in private site login

no refs

- prevents redirect to external sites after providing private site password

Credits: https://github.com/max-schaefer
This commit is contained in:
Thibaut Patel 2021-01-25 14:25:43 +01:00 committed by Daniel Lockyer
parent 7f04ca1bda
commit cd27cba93d
2 changed files with 32 additions and 2 deletions

View file

@ -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 '/';
}

View file

@ -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 = {