Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support subresource integrity #174

Closed
nanaian opened this issue Aug 18, 2019 · 8 comments
Closed

Support subresource integrity #174

nanaian opened this issue Aug 18, 2019 · 8 comments

Comments

@nanaian
Copy link

@nanaian nanaian commented Aug 18, 2019

It would be incredibly useful for import maps to support subresource integrity hashes that are checked against similar to <script integrity=""/>. This is extra important because one of the primary goals of import mapping is to support delivery from 3rd party CDNs (such as unpkg) -- for security, SRI is almost vital when using an external CDN.

This might come in the form:

{
  "imports": {
    "cool-module": [
      { "url": "https://unpkg.com/cool-module@1.0.0?module", "integrity": "sha384-..." },
      "/node_modules/cool-module/index.js"
    ]
  }
}

Note the new option of a { url, integrity } object in place of a string URL on its own.

Alternatively, a top-level integrity object mapping URL to SRI hash might be a better fit as it is backwards-compatible with existing browser and polyfill implementations, and supports adding SRI for nested imports like cool-module/file.js.

@domenic
Copy link
Collaborator

@domenic domenic commented Aug 18, 2019

Heya, this is out of scope for this repository. See discussion at https://github.com/WICG/import-maps#supplying-out-of-band-metadata-for-each-module and the previous similar iissue, #99.

I'll close this since we won't be working on it in this repository, but I'm happy to continue discussing in the close thread.

@domenic domenic closed this as completed Aug 18, 2019
@shannonmoeller
Copy link

@shannonmoeller shannonmoeller commented Oct 8, 2019

+1 to the idea of using import maps for subresource integrity as import in JS and @import in CSS have no way to specify a sha. Import maps feel like a natural fit for this. Is there documentation, discussion, or an alternate proposal on the topic elsewhere, if not here or #99?

@brettz9
Copy link

@brettz9 brettz9 commented Jul 17, 2020

The slides at https://docs.google.com/presentation/d/1qfoLTniLUVJ5YNFrha7BaVumAnW0ZgcCfUU8UbyyuYY/edit#slide=id.g1f527b5ce9_0_108 (starting at slide 13) were helpful toward explaining the down-side of modifying the import syntax.

I may still be inadequately informed in my comments here, but have a few thoughts...

Isn't integrity mostly of use with CDN's, which are more likely to be hosting fixed versions (and caching is already an issue there in one sense with any new version causing need for a separate cache)? While CDN's might not currently suffer from transitive dependencies causing breakage, I'd think in some way this would be a feature, as it would help protect against a depender file accidentally expressed to expect an outdated resource or resource chain.

And though there is the difficulty of manually managing integrity meta-data inline, tooling could no doubt help with this, e.g., to get checksums from the likes of local npm copies and expect the same on the CDN, and then rebuilding all of the local ones.

In addition, the out-of-band solution introduces its own additional can-of-worms in that it would break modularity, requiring storage of meta-data on a resource in a manner unconnected directly with that resource.

That all being said, unlike the other meta-data attributes (e.g., cross-origin, etc.) which have an impact on how the application works, integrity might be a special case in that it is just pass-or-fail and the preparer may wish to do their own separate calculation/verification of the hashes anyways--e.g., they could, like custom resolutions in yarn, let one avoid being locked in to a vulnerable dependency. (npm, for a perhaps useful comparison, does its own out-of-band tracking of checksums--not expecting packages to manage this themselves.)

And by the meta-data being stored out-of-band, diff noise would be avoided (though admittedly source files might not be including this meta-data themselves even if dist files were to store the data in-band.)

So maybe the solution is for integrity to be out-of-band, and other meta-data as a syntax change?

@WesleyAC
Copy link

@WesleyAC WesleyAC commented Dec 7, 2021

@domenic, do you know of any current discussion on this? It's been a couple years, and it seems like there's still no way to do this.

Here's my situation:

  • I'm writing a library that's shipped as a ES6 module — my users will include it via <script type="module" ...
  • The main script uses dynamic imports in order to avoid loading code that's only used in niche circumstances — the set of things it might potentially load is known statically, dynamic imports are just used to avoid loading unneeded code over the network.
  • I'd like to recommend that users use a CDN include it, but I'm only comfortable doing that if I can have integrity checks on every file that might be loaded. Right now, I can only have integrity checks for the top-level file, which isn't very useful if a attacker can trigger loading one of the secondary files, which isn't integrity-checked.

It seems like there's currently no way to do this? Is there anywhere you know of where discussion is happening on this? If not, do you know of somewhere that it would be productive to restart this discussion?

@WesleyAC
Copy link

@WesleyAC WesleyAC commented Dec 7, 2021

I should note for other wanderers that <link type="modulepreload" integrity="..." ... may work for some usecases, but AFAICT not for mine — I don't see a way to tell the browser that the preloading is just so that it knows the integrity hash, but not to actually load the file over the network until it's needed. Possibly a new attribute for link specifying that would be a good solution? (Or perhaps I'm missing an existing one that already does this)

I guess a "solution" might be to write a wrapper around import that injects a link tag onto the page before calling import? That seems like a awful hack for something that should already exist, though.

@guybedford
Copy link
Collaborator

@guybedford guybedford commented Dec 7, 2021

@WesleyAC thanks for poking at this, that's a great summary. Moving forward it seems we have three options:

  1. Have a link preload for not actually preloading. See eg https://lists.w3.org/Archives/Public/public-webappsec/2021Mar/0002.html.
  2. Include integrity in the import map itself. See eg https://github.com/guybedford/import-maps-extensions#integrity
  3. Rely on bundlers that perform dynamic import wrapping, although this will tie cache digests to sources unless that technique can in turn use a bundle manifest, say eg a <script type="bundle-manifest"> that the bundler can read.

I would also really appreciate knowing which way to go here - I'm personally happy to work on specifying any standards work here, it just depends on where the implementation direction lands.

@shannonmoeller
Copy link

@shannonmoeller shannonmoeller commented Dec 7, 2021

fwiw, I'm personally a fan of 2. as it keeps the url and the sha in the same place and lets you provide the integrity sha of dependencies of dependencies.

There is perhaps room for a fourth option using import assertions, but that seems out of scope for import maps:

import { camelCase } from 'https://unpkg.com/lodash' assert {
  integrity: "sha384-...",
  crossorigin: "anonymous",
};

@domenic
Copy link
Collaborator

@domenic domenic commented Dec 7, 2021

Note that the most recent discussion are in #221; in particular see my thoughts in #221 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants