Using nscl patchWorkers in Firefox

General discussion on the NoScript Commons Library. For bug reports or RFEs please use the issue tracker at https://github.com/hackademix/nscl
barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Using nscl patchWorkers in Firefox

Post by barbaz » Sun Dec 26, 2021 10:59 pm

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!
*Always* check the changelogs BEFORE updating that important software!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Mon Dec 27, 2021 10:27 pm

barbaz wrote:
Sun Dec 26, 2021 10:59 pm
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.
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);
Your patch will be automatically injecied as a preamble in every worker.
barbaz wrote:
Sun Dec 26, 2021 10:59 pm
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)?
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

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Mon Dec 27, 2021 11:15 pm

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 -

Code: Select all

TypeError: can't access property "prototype", ServiceWorkerContainer is undefined patchWorkers.js:195:9
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?
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).
Just to be clear, it won't affect CSP-based SRI (e.g. worker-src specified as checksum) either?
*Always* check the changelogs BEFORE updating that important software!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Tue Dec 28, 2021 8:19 am

barbaz wrote:
Mon Dec 27, 2021 11:15 pm
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?
Done, thanks.
barbaz wrote:
Mon Dec 27, 2021 11:15 pm
Just to be clear, it won't affect CSP-based SRI (e.g. worker-src specified as checksum) either?
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

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Tue Dec 28, 2021 3:12 pm

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 -

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>
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?
*Always* check the changelogs BEFORE updating that important software!
-

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Sat Jan 01, 2022 8:30 pm

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!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Mon Jan 03, 2022 10:45 pm

barbaz wrote:
Sat Jan 01, 2022 8:30 pm
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?
Bug. Fixed here, thank you!
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Tue Jan 04, 2022 1:48 am

Thanks Giorgio, SharedWorker are now patched! 8-)

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.'));
  });
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 -

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!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Tue Jan 04, 2022 9:17 am

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
Fixed here, thanks.
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Wed Jan 05, 2022 1:11 am

Great! Image

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');
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.
*Always* check the changelogs BEFORE updating that important software!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Tue Jan 11, 2022 10:31 pm

barbaz wrote:
Wed Jan 05, 2022 1:11 am
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.
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

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Tue Jan 11, 2022 11:24 pm

Is fixed. Thank you! :D
*Always* check the changelogs BEFORE updating that important software!
-

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Mon Jan 17, 2022 6:11 pm

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.)
*Always* check the changelogs BEFORE updating that important software!
-

User avatar
Giorgio Maone
Site Admin
Posts: 9186
Joined: Wed Mar 18, 2009 11:22 pm
Location: Palermo - Italy
Contact:

Re: Using nscl patchWorkers in Firefox

Post by Giorgio Maone » Mon Jan 17, 2022 8:46 pm

barbaz wrote:
Mon Jan 17, 2022 6:11 pm
Is the bug in my extension or nscl?
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

barbaz
Senior Member
Posts: 10122
Joined: Sat Aug 03, 2013 5:45 pm

Re: Using nscl patchWorkers in Firefox

Post by barbaz » Tue Jan 18, 2022 9:04 pm

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!
-

Post Reply