0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -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 a36f8900a2
commit c44f42e307
No known key found for this signature in database
GPG key ID: FFBC6FA2A6F6ABC1
2 changed files with 33 additions and 4 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');
@ -22,10 +21,14 @@ function verifySessionHash(salt, hash) {
}
function getRedirectUrl(query) {
const redirect = decodeURIComponent(query.r || '/');
try {
return url.parse(redirect).pathname;
const redirect = decodeURIComponent(query.r || '/');
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

@ -232,6 +232,32 @@ describe('Private Blogging', function () {
res.redirect.args[0][0].should.be.equal('/');
});
it('authenticateProtection 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.authenticateProtection(req, res, next);
res.redirect.called.should.be.true();
res.redirect.args[0][0].should.be.equal('/test');
});
it('authenticateProtection 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.authenticateProtection(req, res, next);
res.redirect.called.should.be.true();
res.redirect.args[0][0].should.be.equal('/');
});
it('filterPrivateRoutes should 404 for /rss/ requests', function () {
var salt = Date.now().toString();
req.url = req.path = '/rss/';