Skip to content

Commit

Permalink
Mind that BroadcastChannel contructor can throw in Firefox
Browse files Browse the repository at this point in the history
BroadcastChannel constructor throws in Firefox when Enhanced
Tracking Protection is set to "strict".

This behavior could cause scriptlet injection to wholly break
when uBO's logger was opened, as BroadcastChannel() is used
by scriptlets to report information to the logger.

This commit ensures that exceptions from BroadcastChannel
constructor are properly handled.

The scriptlets will fall back to report at the console should
they be unable to report to the logger through BroadcastChannel.
  • Loading branch information
gorhill committed Oct 5, 2024
1 parent 4169340 commit 6d2b337
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 46 deletions.
67 changes: 39 additions & 28 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ function safeSelf() {
scriptletGlobals.safeSelf = safe;
if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
// This is executed only when the logger is opened
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
let bcBuffer = [];
safe.logLevel = scriptletGlobals.logLevel || 1;
let lastLogType = '';
let lastLogText = '';
let lastLogTime = 0;
safe.sendToLogger = (type, ...args) => {
safe.toLogText = (type, ...args) => {
if ( args.length === 0 ) { return; }
const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
if ( text === lastLogText && type === lastLogType ) {
Expand All @@ -188,30 +186,45 @@ function safeSelf() {
lastLogType = type;
lastLogText = text;
lastLogTime = Date.now();
if ( bcBuffer === undefined ) {
return bc.postMessage({ what: 'messageToLogger', type, text });
}
bcBuffer.push({ type, text });
};
bc.onmessage = ev => {
const msg = ev.data;
switch ( msg ) {
case 'iamready!':
if ( bcBuffer === undefined ) { break; }
bcBuffer.forEach(({ type, text }) =>
bc.postMessage({ what: 'messageToLogger', type, text })
);
bcBuffer = undefined;
break;
case 'setScriptletLogLevelToOne':
safe.logLevel = 1;
break;
case 'setScriptletLogLevelToTwo':
safe.logLevel = 2;
break;
}
return text;
};
bc.postMessage('areyouready?');
try {
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
let bcBuffer = [];
safe.sendToLogger = (type, ...args) => {
const text = safe.toLogText(type, ...args);
if ( text === undefined ) { return; }
if ( bcBuffer === undefined ) {
return bc.postMessage({ what: 'messageToLogger', type, text });
}
bcBuffer.push({ type, text });
};
bc.onmessage = ev => {
const msg = ev.data;
switch ( msg ) {
case 'iamready!':
if ( bcBuffer === undefined ) { break; }
bcBuffer.forEach(({ type, text }) =>
bc.postMessage({ what: 'messageToLogger', type, text })
);
bcBuffer = undefined;
break;
case 'setScriptletLogLevelToOne':
safe.logLevel = 1;
break;
case 'setScriptletLogLevelToTwo':
safe.logLevel = 2;
break;
}
};
bc.postMessage('areyouready?');
} catch(_) {
safe.sendToLogger = (type, ...args) => {
const text = safe.toLogText(type, ...args);
if ( text === undefined ) { return; }
console.log(`uBO${text}`);
};
}
return safe;
}

Expand Down Expand Up @@ -5144,7 +5157,6 @@ function trustedPreventXhr(...args) {
}

/**
*
* @trustedScriptlet trusted-prevent-dom-bypass
*
* @description
Expand Down Expand Up @@ -5219,7 +5231,6 @@ function trustedPreventDomBypass(
}

/**
*
* @trustedScriptlet trusted-override-element-method
*
* @description
Expand Down
39 changes: 21 additions & 18 deletions src/js/scriptlet-filtering.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,25 +176,28 @@ const onScriptletMessageInjector = (( ) => {
'(',
function(name) {
if ( self.uBO_bcSecret ) { return; }
const bcSecret = new self.BroadcastChannel(name);
bcSecret.onmessage = ev => {
const msg = ev.data;
switch ( typeof msg ) {
case 'string':
if ( msg !== 'areyouready?' ) { break; }
bcSecret.postMessage('iamready!');
break;
case 'object':
if ( self.vAPI && self.vAPI.messaging ) {
self.vAPI.messaging.send('contentscript', msg);
} else {
console.log(`[uBO][${msg.type}]${msg.text}`);
try {
const bcSecret = new self.BroadcastChannel(name);
bcSecret.onmessage = ev => {
const msg = ev.data;
switch ( typeof msg ) {
case 'string':
if ( msg !== 'areyouready?' ) { break; }
bcSecret.postMessage('iamready!');
break;
case 'object':
if ( self.vAPI && self.vAPI.messaging ) {
self.vAPI.messaging.send('contentscript', msg);
} else {
console.log(`[uBO][${msg.type}]${msg.text}`);
}
break;
}
break;
}
};
bcSecret.postMessage('iamready!');
self.uBO_bcSecret = bcSecret;
};
bcSecret.postMessage('iamready!');
self.uBO_bcSecret = bcSecret;
} catch(_) {
}
}.toString(),
')(',
'bcSecret-slot',
Expand Down

0 comments on commit 6d2b337

Please sign in to comment.