Added x-frame-options header to /ghost/ route (#10760)

no issue
- by default the `/ghost/` route will add an `x-frame-options: sameorigin` header to the response to help protect the admin area against clickjacking
- the header can be disabled by adding `"adminFrameProtection": false` to the `config.{env}.json` configuration file

Credits: Muhammad Fawwad Obaida
This commit is contained in:
Kevin Ansfield 2019-05-28 09:04:48 +01:00 committed by GitHub
parent 5ee76a3f85
commit f88adb9180
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 1 deletions

View File

@ -94,5 +94,6 @@
},
"compress": true,
"preloadHeaders": false,
"adminFrameProtection": true,
"sendWelcomeEmail": true
}

View File

@ -23,6 +23,11 @@ module.exports = function adminController(req, res) {
const defaultTemplate = config.get('env') === 'production' ? 'default-prod.html' : 'default.html';
const templatePath = path.resolve(config.get('paths').adminViews, defaultTemplate);
const headers = {};
res.sendFile(templatePath);
if (config.get('adminFrameProtection')) {
headers['X-Frame-Options'] = 'sameorigin';
}
res.sendFile(templatePath, {headers});
};

View File

@ -0,0 +1,45 @@
require('should');
const sinon = require('sinon');
const configUtils = require('../../../utils/configUtils');
const controller = require('../../../../server/web/admin/controller');
describe('Admin App', function () {
describe('controller', function () {
const req = {};
let res;
beforeEach(function () {
res = {
sendFile: sinon.spy()
};
configUtils.restore();
});
afterEach(function () {
sinon.restore();
});
it('adds x-frame-options header when adminFrameProtection is enabled (default)', function () {
// default config: configUtils.set('adminFrameProtection', true);
controller(req, res);
res.sendFile.called.should.be.true();
res.sendFile.calledWith(
sinon.match.string,
sinon.match.hasNested('headers.X-Frame-Options', sinon.match('sameorigin'))
).should.be.true();
});
it('doesn\'t add x-frame-options header when adminFrameProtection is disabled', function () {
configUtils.set('adminFrameProtection', false);
controller(req, res);
res.sendFile.called.should.be.true();
res.sendFile.calledWith(
sinon.match.string,
sinon.match.hasNested('headers.X-Frame-Options')
).should.be.false();
});
});
});