greasyfork icon indicating copy to clipboard operation
greasyfork copied to clipboard

Consider permitting loading remote scripts with subresource integrity hashes

Open ppixiv opened this issue 2 years ago • 10 comments

GF's policy on loading remote scripts makes sense. Openly loading scripts from untrusted sites would allow authors to change scripts without anyone having the ability to audit the changes. The 2MB maximum size policy is reasonable too, since people stuffing 50MB of data in every version of a script could explode the storage and bandwidth requirements of the site.

But my script is 1.4 MB and slowly growing. It's a complex script that completely replaces the UI for a site. It's not 2MB, but it's gradually edging upwards, and I'm going to be at a dead-end if I reach that point. Moving the graphics and stylesheets out wouldn't do much (maybe 100k), it's almost all code.

It would be great if remote scripts were permitted, as long as subresource integrity is used to prevent them from being modified. You're probably already familiar with this, but for reference:

https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity

using

That way, authors can't modify scripts without publishing a new corresponding version of the userscript with the new hashes, so everything stays locked to the update process.

I doubt too many people would bother to do this, but it would be really useful for people running up against the size cap.

ppixiv avatar Jun 25 '22 05:06 ppixiv

Would this be via @require or @resource? Do any user script managers support subresource integrity in those keys?

JasonBarnabe avatar Jun 26 '22 00:06 JasonBarnabe

It would only be by creating script tags, or loading scripts with fetch. But if this was allowed on GF, I'd probably consider filing feature requests on script managers to add native support for this if there was some way to do it that made sense syntactically.

ppixiv avatar Jun 26 '22 00:06 ppixiv

Do any user script managers support subresource integrity in those keys?

Tampermonkey supports SRI

derjanb avatar Jun 26 '22 18:06 derjanb

Would be willing to ping GM and VM and see if they're interested in implementing this (and maybe doing some of it myself if necessary) if it would make this more worthwhile. I can do fetches directly to guarantee the hash is always verified, but having it supported natively by script managers definitely makes it easier for developers to use.

ppixiv avatar Jun 28 '22 06:06 ppixiv

If Greasy Fork were to allow external scripts with subresource integrity hashes:

  1. We would have no history of the content of the page, so if a script did something bad in its subscript, got reported, then changed it, we wouldn't know what exactly it did before. Not a deal-breaker.
  2. We would likely need to enforce various rules on the subresource, like anti-obfuscation, otherwise it would be easy to hide bad things in it.
  3. We would require that any sub-subresource loaded also follows the same rules.

JasonBarnabe avatar Sep 11 '22 14:09 JasonBarnabe

For hashed @resource/@require tags, you could store the contents of subresources along with script history, so it's available even if the contents change in an update, and diffs on the site could still work even if chunks of code are external. Probably overkill, and makes it take a bunch of dev work instead of just a policy change, but it's always possible in the future if wanted. It would make subresources take your disk space, but not your bandwidth.

I assume that the whole script would be under the same rules ("keep the code readable", etc.), regardless of how it's distributed.

ppixiv avatar Sep 12 '22 10:09 ppixiv

@derjanb Two things are not 100% clear to me after reading http://tmnk.net/documentation.php#Subresource_Integrity :

  1. What happens if there are hashes present on a subresource but none of the algorithms are supported by TM? Is the subresource made available to the script?
  2. "TM supports SHA-256 and MD5 hashes natively, all other (SHA-1, SHA-384 and SHA-512) depend on window.crypto." - meaning TM supports SHA-256, MD5, and anything the browser supports through window.crypto.subtle.digest?

JasonBarnabe avatar Sep 15 '22 01:09 JasonBarnabe

I tried setting the hash to "unsupported=90fec896bf599e5cfc1d9ce7ded6ee64207f40b8f3ced2b348b990766de89e86", and it did load the script, so the fallback if it doesn't understand any hashes is to load the script anyway. I'm not sure I agree with that behavior, since it means script authors might think they've set up SRI since the script is loading, or users might think a resource can't change, when it's actually doing nothing. Maybe it's for backwards-compatibility, in case there's something unrelated in the hash for some reason.

If you want, you could improve this by scanning @require/@resource tags, and checking that each one has an SHA256 hash in the list, so there's at least one known-functioning hash. That would prevent scripts from (maliciously or accidentally) having SRI tags that don't actually do anything, like "SHA-5I2", since they would always have at least that known-good hash.

#2: Seems like it. I tested with an SHA-1 hash, and that worked, which would have come from window.crypto.

ppixiv avatar Sep 15 '22 03:09 ppixiv

@JasonBarnabe

What happens if there are hashes present on a subresource but none of the algorithms are supported by TM? Is the subresource made available to the script?

It depends. Tampermonkey has a setting called "Security > Subresource Integrity". The default is "Validate if possible", which basically means given supported hashes need to be valid and unknown hash types are ignored.

"Validate if given" ignores all resources that can't be validated sucessfully if any hash is given.

"Enforce" makes TM forward only validated resources.

TM supports SHA-256, MD5, and anything the browser supports through window.crypto.subtle.digest

SHA-256, MD5, SHA-1, SHA-384, SHA-512 at the moment. I can add others if sensible.

derjanb avatar Sep 15 '22 06:09 derjanb

Greasy Fork will now read and monitor subresource integrity uses, alerting authors if there is a problem. See discussion here.

With this in place, I will be updating Greasy Fork's policy on external scripts to allow use of arbitrary URLs with subresource integrity, subject to some conditions. The policy is not changed yet so don't try to test it, but just communicating that the change is coming.

JasonBarnabe avatar Sep 19 '22 01:09 JasonBarnabe

External scripts with subresource integrity hashes in the TM format are now allowed as long as they follow the rest of the site's rules.

https://greasyfork.org/en/discussions/greasyfork/150814-rule-change-external-scripts-allowed-with-subresource-integrity

JasonBarnabe avatar Sep 26 '22 00:09 JasonBarnabe

@derjanb What is the exact format TM is expecting for URLs with SRI? Specifically I ask because on https://www.tampermonkey.net/documentation.php#Subresource_Integrity, the first 3 examples separate the hash method (md5, sha256, etc.) and the actual hash with =, while the last 2 use -. Are both formats allowed, or is this a typo?

JasonBarnabe avatar Oct 15 '22 00:10 JasonBarnabe