Using nscl patchWorkers in Firefox
Using nscl patchWorkers in Firefox
I have a custom Firefox extension that would benefit from being able to run scripts in worker scopes. It seems there is no direct WebExtensions API for this, but nscl has patchWorkers which provides this functionality. I would like to use nscl patchWorkers, but I have two questions:
1) How to use patchWorkers in an extension? I haven't been able to deduce it from reading the code, and I can't find documentation saying how to use it.
2) In Firefox patchWorkers seems to add data to every script using filterResponseData. So will using patchWorkers break websites that validate a checksum of script resources using Web-standard APIs for that (e.g. Subresource Integrity)?
Thanks!
1) How to use patchWorkers in an extension? I haven't been able to deduce it from reading the code, and I can't find documentation saying how to use it.
2) In Firefox patchWorkers seems to add data to every script using filterResponseData. So will using patchWorkers break websites that validate a checksum of script resources using Web-standard APIs for that (e.g. Subresource Integrity)?
Thanks!
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
Just include both nscl/service/patchWorkers.js in the background script and nscl/content/patchWorkers.js as a content script, and register your patch(es) from your own content script (of course "run_at": "document_start") like this:
Code: Select all
patchWorkers(yourCodeAsAStringOrAFunction);
It doesn't happen for every script, but only for service worker files loaded via navigator.serviceWorker.register() (which, AFAICT, does not support SRI).
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Thanks for the reply Giorgio. I've now got patchWorkers (+ its dependencies) in my extension but it's still not working: it assumes that about:config > dom.serviceWorkers.enabled is set to true, and errors out if that's false -
If patchWorkers only does ServiceWorker scopes, it's up to me to account for that in my extension code. But if it does other types of workers as well (which is what I'm seeking) then, since there are surely other end-users of nscl-based extensions who disable ServiceWorkers this way, could this please be fixed in nscl?
EDIT If this should be fixed in nscl, I might be able to try to write a patch, quick look suggests just adding an extra check here might be enough?
Code: Select all
TypeError: can't access property "prototype", ServiceWorkerContainer is undefined patchWorkers.js:195:9
EDIT If this should be fixed in nscl, I might be able to try to write a patch, quick look suggests just adding an extra check here might be enough?
Just to be clear, it won't affect CSP-based SRI (e.g. worker-src specified as checksum) either?Giorgio Maone wrote: ↑Mon Dec 27, 2021 10:27 pm It doesn't happen for every script, but only for service worker files loaded via navigator.serviceWorker.register() (which, AFAICT, does not support SRI).
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
Done, thanks.
I believe it won't, based on https://github.com/w3c/webappsec-subres ... /issues/66, but it would be great if you could actually test this assumption.
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Sorry, this is my first time working with CSP and non-ServiceWorker types of Web Workers, and I couldn't figure out how to get a working example?
I put this PHP code up on my local server -
Worker.js and SharedWorker.js both exist, but so far do nothing (they only contain comment).
Unfortunately both my workers are blocked by this CSP, even in a new Firefox profile with no extensions. What am I doing wrong?
I put this PHP code up on my local server -
Code: Select all
<!doctype html>
<head>
<meta http-equiv="content-security-policy" content="worker-src <?php
function sha384($fn) {
$f = fopen($fn, "r") or die("can't read $fn");
$fdata = fread($f, filesize($fn));
fclose($f);
$thehash = hash('sha384', $fdata, true);
return 'sha384-' . base64_encode($thehash);
}
echo sha384('Worker.js') . ' ' . sha384('SharedWorker.js');
?>;">
<script>window.addEventListener('DOMContentLoaded', function() {
let nw = new Worker('./Worker.js');
let shw = new SharedWorker('./SharedWorker.js');
}, false);
</script>
</head>
<body>
</body>
Unfortunately both my workers are blocked by this CSP, even in a new Firefox profile with no extensions. What am I doing wrong?
*Always* check the changelogs BEFORE updating that important software!
-
Re: Using nscl patchWorkers in Firefox
I commented out the CSP just to check that I had working code in my extension and test page, and discovered that patchWorkers patches Worker() but not SharedWorker(). Is that expected behavior? If so, how to also patch SharedWorker using nscl?
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
Bug. Fixed here, thank you!
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Thanks Giorgio, SharedWorker are now patched!
Unfortunately there is another issue: any use of patchWorkers breaks webpages that use SharedWorker.port.close(). Example webpage code -
With no use of nscl patchWorkers, this code works as expected. When nscl patchWorkers is used, the SharedWorker starts and sends a message, but the appendChild line in that event listener is never reached, instead this error happens -
![Cool 8-)](./images/smilies/icon_cool.gif)
Unfortunately there is another issue: any use of patchWorkers breaks webpages that use SharedWorker.port.close(). Example webpage code -
Code: Select all
let shw = new SharedWorker('./SharedWorker.js');
// Test MessagePort
shw.port.start();
shw.port.addEventListener('message', function(m) {
console.log('Closing port on receipt of ', m.data);
shw.port.close();
document.body.appendChild(document.createTextNode('SharedWorker closed port successfully.'));
});
Code: Select all
Uncaught TypeError: 'close' called on an object that does not implement interface MessagePort
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
Fixed here, thanks.barbaz wrote: ↑Tue Jan 04, 2022 1:48 am When nscl patchWorkers is used, the SharedWorker starts and sends a message, but the appendChild line in that event listener is never reached, instead this error happens -Code: Select all
Uncaught TypeError: 'close' called on an object that does not implement interface MessagePort
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Great! ![Image](http://i.psyche.me/thumbsup_left.gif)
So patchWorkers seems to be working if webpage doesn't try to be evasive. But if it does, patchWorkers isn't applied -
My content script is injected into allFrames and matchAboutBlank is set to true as well. Other parts of my content script seem executed in the iframe.
What else should my extension do to patchWorkers also in the context of this frame? That is, such that it would also apply to nested about:blank frames.
![Image](http://i.psyche.me/thumbsup_left.gif)
So patchWorkers seems to be working if webpage doesn't try to be evasive. But if it does, patchWorkers isn't applied -
Code: Select all
let ifr = document.createElement('iframe');
//ifr.setAttribute('sandbox', 'allow-same-origin');
document.body.appendChild(ifr);
let f = window.frames[window.length - 1];
let nw = new f.Worker('./Worker.js');
let shw = new f.SharedWorker('./SharedWorker.js');
What else should my extension do to patchWorkers also in the context of this frame? That is, such that it would also apply to nested about:blank frames.
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
It was applied, but being frame loading (and content script initialization) asynchronous, while the window object for ad-interim about:blank frames is available immediately (synchronously) upon creation, the patch was applied too late by one tick.
Quite a hairy problem (and I'm sure pretty much all the "anti-fingerprinting" extensions out there can be fooled by this trick, beside other known ones), but should be fixed here, thanks.
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Is fixed. Thank you! ![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
*Always* check the changelogs BEFORE updating that important software!
-
Re: Using nscl patchWorkers in Firefox
Unfortunately there is still another way to bypass patchWorkers, and I have no idea what it is
The extension I'm making is a UA spoofer, but according to CreepJS main test viewtopic.php?f=18&t=26434 I'm still leaking the real UA in workers. It only happens on the main test page. On their worker-only test page my extension is working as expected.
How is it getting the real UA? Is the bug in my extension or nscl?
(Testing this does not require allowing the 3rd party sites CreepJS calls. The problem shows up just using the pure JS side of the tests.)
![Confused :?](./images/smilies/icon_e_confused.gif)
The extension I'm making is a UA spoofer, but according to CreepJS main test viewtopic.php?f=18&t=26434 I'm still leaking the real UA in workers. It only happens on the main test page. On their worker-only test page my extension is working as expected.
How is it getting the real UA? Is the bug in my extension or nscl?
(Testing this does not require allowing the 3rd party sites CreepJS calls. The problem shows up just using the pure JS side of the tests.)
*Always* check the changelogs BEFORE updating that important software!
-
- Giorgio Maone
- Site Admin
- Posts: 9468
- Joined: Wed Mar 18, 2009 11:22 pm
- Location: Palermo - Italy
- Contact:
Re: Using nscl patchWorkers in Firefox
Sorry if I missed it, but where's the code of your extension?
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Re: Using nscl patchWorkers in Firefox
Sorry, I didn't post my extension code anywhere as I'm not currently able to deal with maintaining a publicly-available extension. I will try to create a minimal test case for this. EDIT Sent by PM
*Always* check the changelogs BEFORE updating that important software!
-