0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Add config URLS to CORS whitelist

refs #6644

- urls specified in config.js should be considered whitelisted/trusted
- this is not quite straightforward because config.js is not ready at the point the middleware is required
- tests have been updated to cover these new cases + use rewire to override the internal whitelist cache
This commit is contained in:
Hannah Wolfe 2016-04-19 13:38:09 +01:00
parent 164dda9af7
commit 94a4e08809
2 changed files with 69 additions and 8 deletions

View file

@ -2,9 +2,8 @@ var cors = require('cors'),
_ = require('lodash'),
url = require('url'),
os = require('os'),
whitelist = [
'localhost'
],
config = require('../config'),
whitelist = [],
ENABLE_CORS = {origin: true, maxAge: 86400},
DISABLE_CORS = {origin: false};
@ -14,7 +13,9 @@ var cors = require('cors'),
*/
function getIPs() {
var ifaces = os.networkInterfaces(),
ips = [];
ips = [
'localhost'
];
Object.keys(ifaces).forEach(function (ifname) {
ifaces[ifname].forEach(function (iface) {
@ -30,8 +31,27 @@ function getIPs() {
return ips;
}
// origins that always match: localhost, local IPs, etc.
whitelist = whitelist.concat(getIPs());
function getUrls() {
var urls = [url.parse(config.url).hostname];
if (config.urlSSL) {
urls.push(url.parse(config.urlSSL).hostname);
}
return urls;
}
function getWhitelist() {
// This needs doing just one time after init
if (_.isEmpty(whitelist)) {
// origins that always match: localhost, local IPs, etc.
whitelist = whitelist.concat(getIPs());
// Trusted urls from config.js
whitelist = whitelist.concat(getUrls());
}
return whitelist;
}
/**
* Checks the origin and enables/disables CORS headers in the response.
@ -54,7 +74,7 @@ function handleCORS(req, cb) {
}
// Origin matches whitelist
if (whitelist.indexOf(url.parse(origin).hostname) > -1) {
if (getWhitelist().indexOf(url.parse(origin).hostname) > -1) {
return cb(null, ENABLE_CORS);
}

View file

@ -1,7 +1,9 @@
/*globals describe, it, beforeEach, afterEach */
var sinon = require('sinon'),
should = require('should'),
cors = require('../../../server/middleware/cors');
rewire = require('rewire'),
configUtils = require('../../utils/configUtils'),
cors = rewire('../../../server/middleware/cors');
describe('cors', function () {
var res, req, next, sandbox;
@ -31,6 +33,8 @@ describe('cors', function () {
afterEach(function () {
sandbox.restore();
configUtils.restore();
cors = rewire('../../../server/middleware/cors');
});
it('should not be enabled without a request origin header', function (done) {
@ -137,4 +141,41 @@ describe('cors', function () {
done();
});
it('should be enabled if the origin matches config.url', function (done) {
var origin = 'http://my.blog';
configUtils.set({
url: origin
});
req.get = sinon.stub().withArgs('origin').returns(origin);
res.get = sinon.stub().withArgs('origin').returns(origin);
req.headers.origin = origin;
cors(req, res, next);
next.called.should.be.true();
res.headers['Access-Control-Allow-Origin'].should.equal(origin);
done();
});
it('should be enabled if the origin matches config.urlSSL', function (done) {
var origin = 'https://secure.blog';
configUtils.set({
url: 'http://my.blog',
urlSSL: origin
});
req.get = sinon.stub().withArgs('origin').returns(origin);
res.get = sinon.stub().withArgs('origin').returns(origin);
req.headers.origin = origin;
cors(req, res, next);
next.called.should.be.true();
res.headers['Access-Control-Allow-Origin'].should.equal(origin);
done();
});
});