mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-04 10:09:38 +02:00
Use Blob URLs to reliably inject scriptlets
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/235 Fixed as suggested by <https://github.com/evilpie>, to safely bypass a page's own CSP.
This commit is contained in:
parent
1b63d65ac6
commit
0971025b21
@ -465,16 +465,21 @@ vAPI.SafeAnimationFrame = class {
|
|||||||
|
|
||||||
vAPI.injectScriptlet = function(doc, text) {
|
vAPI.injectScriptlet = function(doc, text) {
|
||||||
if ( !doc ) { return; }
|
if ( !doc ) { return; }
|
||||||
let script;
|
let script, url;
|
||||||
try {
|
try {
|
||||||
|
const blob = new self.Blob([ text ], { type: 'text/javascript' });
|
||||||
|
url = self.URL.createObjectURL(blob);
|
||||||
script = doc.createElement('script');
|
script = doc.createElement('script');
|
||||||
script.appendChild(doc.createTextNode(text));
|
script.src = url;
|
||||||
(doc.head || doc.documentElement || doc).appendChild(script);
|
(doc.head || doc.documentElement || doc).appendChild(script);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
if ( script ) {
|
if ( script ) {
|
||||||
script.remove();
|
script.remove();
|
||||||
script.textContent = '';
|
script.src = '';
|
||||||
|
}
|
||||||
|
if ( url ) {
|
||||||
|
self.URL.revokeObjectURL(url);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
const extToMimeMap = new Map([
|
const extToMimeMap = new Map([
|
||||||
[ 'gif', 'image/gif' ],
|
[ 'gif', 'image/gif' ],
|
||||||
[ 'html', 'text/html' ],
|
[ 'html', 'text/html' ],
|
||||||
[ 'js', 'application/javascript' ],
|
[ 'js', 'text/javascript' ],
|
||||||
[ 'mp3', 'audio/mp3' ],
|
[ 'mp3', 'audio/mp3' ],
|
||||||
[ 'mp4', 'video/mp4' ],
|
[ 'mp4', 'video/mp4' ],
|
||||||
[ 'png', 'image/png' ],
|
[ 'png', 'image/png' ],
|
||||||
@ -46,7 +46,7 @@ const extToMimeMap = new Map([
|
|||||||
const typeToMimeMap = new Map([
|
const typeToMimeMap = new Map([
|
||||||
[ 'main_frame', 'text/html' ],
|
[ 'main_frame', 'text/html' ],
|
||||||
[ 'other', 'text/plain' ],
|
[ 'other', 'text/plain' ],
|
||||||
[ 'script', 'application/javascript' ],
|
[ 'script', 'text/javascript' ],
|
||||||
[ 'stylesheet', 'text/css' ],
|
[ 'stylesheet', 'text/css' ],
|
||||||
[ 'sub_frame', 'text/html' ],
|
[ 'sub_frame', 'text/html' ],
|
||||||
[ 'xmlhttprequest', 'text/plain' ],
|
[ 'xmlhttprequest', 'text/plain' ],
|
||||||
|
@ -97,19 +97,25 @@ const contentscriptCode = (( ) => {
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let script;
|
let script, url;
|
||||||
try {
|
try {
|
||||||
script = doc.createElement('script');
|
const blob = new self.Blob(
|
||||||
script.appendChild(doc.createTextNode(
|
[ decodeURIComponent(scriptlets) ],
|
||||||
decodeURIComponent(scriptlets))
|
{ type: 'text/javascript' }
|
||||||
);
|
);
|
||||||
|
url = self.URL.createObjectURL(blob);
|
||||||
|
script = doc.createElement('script');
|
||||||
|
script.src = url;
|
||||||
(doc.head || doc.documentElement).appendChild(script);
|
(doc.head || doc.documentElement).appendChild(script);
|
||||||
self.uBO_scriptletsInjected = true;
|
self.uBO_scriptletsInjected = true;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
if ( script ) {
|
if ( script ) {
|
||||||
script.remove();
|
script.remove();
|
||||||
script.textContent = '';
|
script.src = '';
|
||||||
|
}
|
||||||
|
if ( url ) {
|
||||||
|
self.URL.revokeObjectURL(url);
|
||||||
}
|
}
|
||||||
if ( typeof self.uBO_scriptletsInjected === 'boolean' ) { return 0; }
|
if ( typeof self.uBO_scriptletsInjected === 'boolean' ) { return 0; }
|
||||||
}.toString(),
|
}.toString(),
|
||||||
@ -177,10 +183,7 @@ const lookupScriptlet = function(rawToken, reng, toInject) {
|
|||||||
} else {
|
} else {
|
||||||
token = `${token}.js`;
|
token = `${token}.js`;
|
||||||
}
|
}
|
||||||
content = reng.resourceContentFromName(
|
content = reng.resourceContentFromName(token, 'text/javascript');
|
||||||
token,
|
|
||||||
'application/javascript'
|
|
||||||
);
|
|
||||||
if ( !content ) { return; }
|
if ( !content ) { return; }
|
||||||
if ( args ) {
|
if ( args ) {
|
||||||
content = patchScriptlet(content, args);
|
content = patchScriptlet(content, args);
|
||||||
|
Loading…
Reference in New Issue
Block a user