mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Added middleware to prevent other sites' content from being served (#20922)
ref ONC-294 --------- Co-authored-by: Daniel Lockyer <hi@daniellockyer.com>
This commit is contained in:
parent
dd183cf25e
commit
46a4f7bc36
2 changed files with 131 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
const sentry = require('./shared/sentry');
|
||||
const express = require('./shared/express');
|
||||
const config = require('./shared/config');
|
||||
const logging = require('@tryghost/logging');
|
||||
const urlService = require('./server/services/url');
|
||||
|
||||
const fs = require('fs');
|
||||
|
@ -27,12 +28,33 @@ const maintenanceMiddleware = function maintenanceMiddleware(req, res, next) {
|
|||
fs.createReadStream(path.resolve(__dirname, './server/views/maintenance.html')).pipe(res);
|
||||
};
|
||||
|
||||
// Used by Ghost (Pro) to ensure that requests cannot be served by the wrong site
|
||||
const siteIdMiddleware = function siteIdMiddleware(req, res, next) {
|
||||
const configSiteId = config.get('hostSettings:siteId');
|
||||
const headerSiteId = req.headers['x-site-id'];
|
||||
|
||||
if (`${configSiteId}` === `${headerSiteId}`) {
|
||||
return next();
|
||||
}
|
||||
|
||||
logging.warn(`Mismatched site id (expected ${configSiteId}, got ${headerSiteId})`);
|
||||
|
||||
res.set({
|
||||
'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||
});
|
||||
res.writeHead(500);
|
||||
res.end();
|
||||
};
|
||||
|
||||
const rootApp = () => {
|
||||
const app = express('root');
|
||||
app.use(sentry.requestHandler);
|
||||
if (config.get('sentry')?.tracing?.enabled === true) {
|
||||
app.use(sentry.tracingHandler);
|
||||
}
|
||||
if (config.get('hostSettings:siteId')) {
|
||||
app.use(siteIdMiddleware);
|
||||
}
|
||||
app.enable('maintenance');
|
||||
app.use(maintenanceMiddleware);
|
||||
|
||||
|
|
109
ghost/core/test/e2e-frontend/site_id_middleware.test.js
Normal file
109
ghost/core/test/e2e-frontend/site_id_middleware.test.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
const sinon = require('sinon');
|
||||
const supertest = require('supertest');
|
||||
const testUtils = require('../utils');
|
||||
const configUtils = require('../utils/configUtils');
|
||||
|
||||
describe('Site id middleware execution', function () {
|
||||
let request;
|
||||
|
||||
describe('Using site-id middleware', function () {
|
||||
before(async function () {
|
||||
configUtils.set('hostSettings:siteId', '123123');
|
||||
|
||||
// Ensure we do a forced start so that spy is in place when the server starts
|
||||
await testUtils.startGhost({forceStart: true});
|
||||
|
||||
request = supertest.agent(configUtils.config.get('url'));
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
sinon.restore();
|
||||
|
||||
configUtils.restore();
|
||||
|
||||
await testUtils.stopGhost();
|
||||
});
|
||||
|
||||
it('should allow requests with the correct site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', '123123')
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('should allow requests with numeric site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', 123123)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('should prevent requests with incorrect numeric site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', 1231230)
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should allow static asset requests with the correct site id header', function () {
|
||||
return request.get('/content/images/ghost.png')
|
||||
.set('x-site-id', '123123')
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should reject static asset requests without a site id header', function () {
|
||||
return request.get('/content/images/ghost.png')
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should reject requests with an incorrect site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', '456456')
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should reject requests without a site id header', function () {
|
||||
return request.get('/')
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should reject requests with an empty site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', '')
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should reject requests with a malformed site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-ghost-site-id', 'not-a-valid-id')
|
||||
.expect(500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Not using site-id middleware', function () {
|
||||
before(async function () {
|
||||
configUtils.set('hostSettings:siteId', undefined);
|
||||
|
||||
// Ensure we do a forced start so that spy is in place when the server starts
|
||||
await testUtils.startGhost({forceStart: true});
|
||||
|
||||
request = supertest.agent(configUtils.config.get('url'));
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
sinon.restore();
|
||||
|
||||
configUtils.restore();
|
||||
|
||||
await testUtils.stopGhost();
|
||||
});
|
||||
|
||||
it('should allow requests without a site id header', function () {
|
||||
return request.get('/')
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('should allow requests with a site id header', function () {
|
||||
return request.get('/')
|
||||
.set('x-site-id', '123123')
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue