Родитель
9dbb9ac48d
Коммит
41d919c629
|
@ -72,10 +72,6 @@ var conf = module.exports = convict({
|
||||||
default: false,
|
default: false,
|
||||||
doc: 'Only send the "Content-Security-Policy-Report-Only" header'
|
doc: 'Only send the "Content-Security-Policy-Report-Only" header'
|
||||||
},
|
},
|
||||||
reportSampleRate: {
|
|
||||||
default: 10,
|
|
||||||
doc: 'Sample rate at which CSP violation reports should be logged'
|
|
||||||
},
|
|
||||||
reportUri: {
|
reportUri: {
|
||||||
default: '/_/csp-violation',
|
default: '/_/csp-violation',
|
||||||
doc: 'Location of "report-uri"'
|
doc: 'Location of "report-uri"'
|
||||||
|
|
|
@ -28,8 +28,7 @@ module.exports = function (config, i18n) {
|
||||||
require('./routes/get-client.json')(i18n),
|
require('./routes/get-client.json')(i18n),
|
||||||
require('./routes/post-metrics')(),
|
require('./routes/post-metrics')(),
|
||||||
require('./routes/post-csp')({
|
require('./routes/post-csp')({
|
||||||
path: config.get('csp.reportUri'),
|
path: config.get('csp.reportUri')
|
||||||
reportSampleRate: config.get('csp.reportSampleRate')
|
|
||||||
}),
|
}),
|
||||||
require('./routes/get-metrics-errors')(),
|
require('./routes/get-metrics-errors')(),
|
||||||
require('./routes/get-openid-login')(config),
|
require('./routes/get-openid-login')(config),
|
||||||
|
|
|
@ -9,30 +9,12 @@
|
||||||
module.exports = function (options) {
|
module.exports = function (options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
/**
|
|
||||||
* 'reportSampleRate' % of messages.
|
|
||||||
* @param reportSampleRate
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
function isSampledUser() {
|
|
||||||
// random between 0 and 100, inclusive
|
|
||||||
var rand = Math.floor(Math.random() * (100 + 1));
|
|
||||||
return rand < options.reportSampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
path: options.path,
|
path: options.path,
|
||||||
process: function (req, res) {
|
process: function (req, res) {
|
||||||
res.json({result: 'ok'});
|
res.json({result: 'ok'});
|
||||||
|
|
||||||
// TODO: This is a temporary measure
|
|
||||||
// Not sure how many CSP errors we will get, for now we rate limit this.
|
|
||||||
// To avoid overflowing Heka logs rate limit the logging
|
|
||||||
if (! isSampledUser()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! req.body || ! req.body['csp-report']) {
|
if (! req.body || ! req.body['csp-report']) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -42,11 +24,16 @@ module.exports = function (options) {
|
||||||
var report = req.body['csp-report'];
|
var report = req.body['csp-report'];
|
||||||
|
|
||||||
var entry = {
|
var entry = {
|
||||||
|
agent: req.get('User-Agent'),
|
||||||
blocked: report['blocked-uri'],
|
blocked: report['blocked-uri'],
|
||||||
|
column: report['column-number'],
|
||||||
|
line: report['line-number'],
|
||||||
op: 'server.csp',
|
op: 'server.csp',
|
||||||
referrer: report['referrer'],
|
referrer: report['referrer'],
|
||||||
|
sample: report['script-sample'],
|
||||||
|
source: report['source-file'],
|
||||||
time: today.toISOString(),
|
time: today.toISOString(),
|
||||||
violated: report['violated-directive']
|
violated: report['violated-directive'],
|
||||||
};
|
};
|
||||||
|
|
||||||
process.stderr.write(JSON.stringify(entry) + '\n');
|
process.stderr.write(JSON.stringify(entry) + '\n');
|
||||||
|
|
|
@ -22,51 +22,33 @@ define([
|
||||||
'csp-report': {
|
'csp-report': {
|
||||||
'blocked-uri': 'http://bing.com'
|
'blocked-uri': 'http://bing.com'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
'get': function () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var mockResponse = {
|
var mockResponse = {
|
||||||
json: function () {}
|
json: function () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
suite['it drops if no csp-report set'] = function () {
|
suite['it drops if no csp-report set'] = function () {
|
||||||
var options = {
|
var postCsp = proxyquire(path.join(process.cwd(), 'server', 'lib', 'routes', 'post-csp'), {})();
|
||||||
reportSampleRate: 100
|
|
||||||
};
|
|
||||||
var postCsp = proxyquire(path.join(process.cwd(), 'server', 'lib', 'routes', 'post-csp'), {})(options);
|
|
||||||
assert.isFalse(postCsp.process({
|
assert.isFalse(postCsp.process({
|
||||||
body: {}
|
body: {},
|
||||||
|
'get': function () {}
|
||||||
}, mockResponse));
|
}, mockResponse));
|
||||||
|
|
||||||
assert.isTrue(postCsp.process({
|
assert.isTrue(postCsp.process({
|
||||||
body: {
|
body: {
|
||||||
'csp-report': {}
|
'csp-report': {}
|
||||||
}
|
},
|
||||||
|
'get': function () {}
|
||||||
}, mockResponse));
|
}, mockResponse));
|
||||||
|
|
||||||
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
suite['it works with csp reports'] = function () {
|
||||||
suite['it allows no messages with 0% sample rate '] = function () {
|
var postCsp = proxyquire(path.join(process.cwd(), 'server', 'lib', 'routes', 'post-csp'), {})();
|
||||||
var options = {
|
|
||||||
reportSampleRate: 0
|
|
||||||
};
|
|
||||||
var postCsp = proxyquire(path.join(process.cwd(), 'server', 'lib', 'routes', 'post-csp'), {})(options);
|
|
||||||
|
|
||||||
// check 5 times that all messages come through
|
|
||||||
assert.isFalse(postCsp.process(mockRequest, mockResponse));
|
|
||||||
assert.isFalse(postCsp.process(mockRequest, mockResponse));
|
|
||||||
assert.isFalse(postCsp.process(mockRequest, mockResponse));
|
|
||||||
assert.isFalse(postCsp.process(mockRequest, mockResponse));
|
|
||||||
assert.isFalse(postCsp.process(mockRequest, mockResponse));
|
|
||||||
};
|
|
||||||
|
|
||||||
suite['it allows all messages with 100% sample rate'] = function () {
|
|
||||||
var options = {
|
|
||||||
reportSampleRate: 100
|
|
||||||
};
|
|
||||||
|
|
||||||
var postCsp = proxyquire(path.join(process.cwd(), 'server', 'lib', 'routes', 'post-csp'), {})(options);
|
|
||||||
// check 5 times that all messages drop
|
// check 5 times that all messages drop
|
||||||
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
||||||
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
assert.isTrue(postCsp.process(mockRequest, mockResponse));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче