mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-06 19:02:30 +01:00
code review: simplify CSP injection code
This commit is contained in:
parent
5c9ffd9af5
commit
3ce3ed2a0e
@ -537,39 +537,22 @@ var foilLargeMediaElement = function(pageStore, details) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var foilWithCSP = function(headers, noInlineScript, noWebsocket, noWorker) {
|
var foilWithCSP = function(headers, noInlineScript, noWebsocket, noBlobWorker) {
|
||||||
var me = foilWithCSP,
|
var i = headerIndexFromName('content-security-policy', headers),
|
||||||
i = headerIndexFromName('content-security-policy', headers),
|
cspSubset = [];
|
||||||
before = i === -1 ? '' : headers[i].value.trim(),
|
|
||||||
after = before;
|
|
||||||
|
|
||||||
if ( noInlineScript ) {
|
if ( noInlineScript ) {
|
||||||
after = foilWithCSPDirective(
|
cspSubset.push("script-src 'unsafe-eval' *");
|
||||||
after,
|
|
||||||
me.reScriptSrc,
|
|
||||||
"script-src 'unsafe-eval' *",
|
|
||||||
me.reScriptSrcRemove
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( noWebsocket ) {
|
if ( noWebsocket ) {
|
||||||
after = foilWithCSPDirective(
|
cspSubset.push('connect-src http: https:');
|
||||||
after,
|
|
||||||
me.reConnectSrc,
|
|
||||||
'connect-src http:',
|
|
||||||
me.reConnectSrcRemove
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/CSP2/#directive-child-src
|
// https://www.w3.org/TR/CSP2/#directive-child-src
|
||||||
// https://www.w3.org/TR/CSP3/#directive-worker-src
|
// https://www.w3.org/TR/CSP3/#directive-worker-src
|
||||||
if ( noWorker ) {
|
if ( noBlobWorker ) {
|
||||||
after = foilWithCSPDirective(
|
cspSubset.push('child-src http: https:');
|
||||||
after,
|
|
||||||
me.reWorkerSrc,
|
|
||||||
'child-src http:',
|
|
||||||
me.reWorkerSrcRemove
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=513860
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=513860
|
||||||
@ -579,89 +562,30 @@ var foilWithCSP = function(headers, noInlineScript, noWebsocket, noWorker) {
|
|||||||
// contexts based on data:- or blob:-based URIs.
|
// contexts based on data:- or blob:-based URIs.
|
||||||
if ( vAPI.chrome && (noInlineScript || noWebsocket) ) {
|
if ( vAPI.chrome && (noInlineScript || noWebsocket) ) {
|
||||||
// https://w3c.github.io/webappsec-csp/#directive-frame-src
|
// https://w3c.github.io/webappsec-csp/#directive-frame-src
|
||||||
after = foilWithCSPDirective(
|
cspSubset.push('frame-src http: https:');
|
||||||
after,
|
|
||||||
me.reFrameSrc,
|
|
||||||
'frame-src http:',
|
|
||||||
me.reFrameSrcRemove
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var changed = after !== before;
|
if ( cspSubset.length === 0 ) { return; }
|
||||||
if ( changed ) {
|
|
||||||
if ( i !== -1 ) {
|
var csp = '';
|
||||||
headers.splice(i, 1);
|
if ( i !== -1 ) {
|
||||||
}
|
csp = headers[i].value.trim();
|
||||||
headers.push({ name: 'Content-Security-Policy', value: after });
|
headers.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
// Use comma to add a new subset to potentially existing one(s). This new
|
||||||
|
// subset has its own reporting options and won't cause spurious CSP
|
||||||
|
// reports to outside world.
|
||||||
|
// Ref.: https://www.w3.org/TR/CSP2/#implementation-considerations
|
||||||
|
cspSubset = cspSubset.join('; ');
|
||||||
|
headers.push({
|
||||||
|
name: 'Content-Security-Policy',
|
||||||
|
value: csp.length === 0 ? cspSubset : csp + ', ' + cspSubset
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
|
||||||
var fn = foilWithCSP;
|
|
||||||
fn.reScriptSrc = /script-src[^;]*;?\s*/;
|
|
||||||
fn.reScriptSrcRemove = /'unsafe-inline'\s*|'nonce-[^']+'\s*/g;
|
|
||||||
fn.reConnectSrc = /connect-src[^;]*;?\s*/;
|
|
||||||
fn.reConnectSrcRemove = /wss?:[^\s]*\s*/g;
|
|
||||||
fn.reWorkerSrc = /child-src[^;]*;?\s*/;
|
|
||||||
fn.reWorkerSrcRemove = /blob:[^\s]*\s*/g;
|
|
||||||
fn.reFrameSrc = /frame-src[^;]*;?\s*/;
|
|
||||||
fn.reFrameSrcRemove = /data:[^\s]*\s*|blob:[^\s]*\s*/g;
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Past issues to keep in mind:
|
|
||||||
// - https://github.com/gorhill/uMatrix/issues/129
|
|
||||||
// - https://github.com/gorhill/uMatrix/issues/320
|
|
||||||
// - https://github.com/gorhill/uBlock/issues/1909
|
|
||||||
|
|
||||||
var foilWithCSPDirective = function(csp, toExtract, toAdd, toRemove) {
|
|
||||||
// Set
|
|
||||||
if ( csp === '' ) {
|
|
||||||
return toAdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
var matches = toExtract.exec(csp);
|
|
||||||
|
|
||||||
// Add
|
|
||||||
if ( matches === null ) {
|
|
||||||
if ( csp.slice(-1) !== ';' ) {
|
|
||||||
csp += ';';
|
|
||||||
}
|
|
||||||
csp += ' ' + toAdd;
|
|
||||||
return csp.replace(reReportDirective, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
var directive = matches[0];
|
|
||||||
|
|
||||||
// No change
|
|
||||||
if ( toRemove.test(directive) === false ) {
|
|
||||||
return csp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove
|
|
||||||
csp = csp.replace(toExtract, '').trim();
|
|
||||||
if ( csp.slice(-1) !== ';' ) {
|
|
||||||
csp += ';';
|
|
||||||
}
|
|
||||||
directive = directive.replace(toRemove, '').trim();
|
|
||||||
|
|
||||||
// Check for empty directive after removal
|
|
||||||
matches = reEmptyDirective.exec(directive);
|
|
||||||
if ( matches ) {
|
|
||||||
directive = matches[1] + " 'none';";
|
|
||||||
}
|
|
||||||
|
|
||||||
csp += ' ' + directive;
|
|
||||||
return csp.replace(reReportDirective, '');
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://w3c.github.io/webappsec-csp/#directives-reporting
|
|
||||||
var reReportDirective = /report-(?:to|uri)[^;]*;?\s*/;
|
|
||||||
var reEmptyDirective = /^([a-z-]+)\s*;/;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Caller must ensure headerName is normalized to lower case.
|
// Caller must ensure headerName is normalized to lower case.
|
||||||
|
Loading…
Reference in New Issue
Block a user