WICG / import-maps

How to control the behavior of JavaScript imports
https://html.spec.whatwg.org/multipage/webappapis.html#import-maps
Other
2.68k stars 69 forks source link

data: / blob: URL mapping #166

Closed guybedford closed 3 years ago

guybedford commented 5 years ago

Brought up by @jkrems on Twitter - do we permit these mappings? And if so, does that mean that a data: URI with a trailing slash is permitted as a folder mapping?

eg:

{
  "data:application/javascript,console.log('test');//null comment//": "https://site.com/"
}

would the above map any content after the data URI above to the local URL? And conversely:

{
  "x/": "data:application/javascript,//"
}

would the above map x/\nconsole.log('hi') into its executable data URI?

bmeck commented 5 years ago

It might make sense to only allow scoping subspaces for special schemes.

hiroshige-g commented 5 years ago

In the current draft spec, the answsers are all Yes, but I think just for generality; There are no specific use cases, while there are no strong reasons to forbid, so the current draft spec is written in an "allow everything" style. If there are concerns, I think we can/should add limitations.

(In general, I'm not confident about how to handle cases that look a bit scary like this; If attackers can inject malicious import maps or malicious specifiers, I expect the attackers should be able to inject malicious scripts directly (this depends on import map+CSP design though), so import maps don't increase attack surfaces. On the other hand, conservatively forbidding scary cases (with no valid use cases) might prevent unexpected security issues. Anyway I welcome inputs)

domenic commented 5 years ago

@bmeck's point about scoping being weird for non-special schemes seems most important here. A scope of "data:application/" means something very different than a scope of "https://application/.

Otherwise I tend to lean toward letting people remap specifiers even if those specifiers look like data: URLs, or using import maps to create aliases for data: URLs instead of importing them directly.

hiroshige-g commented 4 years ago

After #176, the latter case ("x/": "data:application/javascript,//") always fails, because now we handle trailing-slash matching by relative URL parsing (and using data: URLs as base URLs fails). The former case still works.

jakearchibald commented 4 years ago

Can you still map identifiers to data URLs?

I find myself using things like AMD because I can inline many modules in the page. Import maps + data URLs will provide the same functionality.

dcleao commented 4 years ago

@jakearchibald Could you please elaborate? Are you saying you'd be able to have AMD-like bundles (a single JS file) using import maps + data URLs? That's very interesting, but I fail to see how you would achieve that :-/

jakearchibald commented 4 years ago

When we built https://proxx.app/, we wanted to improve performance by inlining the JS for the first interaction. The first interaction was a set of modules, some of which weren't exclusive to the first interaction (eg helper functions).

When the "later interaction" modules loaded, we wanted them to be able to import modules from the initial set that were inlined into the page.

Because AMD allows many modules to be defined in a single script, this was pretty easy to achieve.

I'm wondering if import maps can bring the same functionality to standard modules:

<script type="importmap">
{
  "./utils.mjs": "data:text/javascript;charset=utf-8,export%20const%20log%20%3D%20msg%20%3D%3E%20console.log%28msg%29"
}
</script>
<script type="module">
  import { log } from './utils.mjs';
  log('Hi!');
</script>

In the above, import maps have been used to inline ./utils.mjs.

dcleao commented 4 years ago

Thanks for the explanation. If data URLs are supported, Import maps allow inlining scripts in the import map itself. That's great (minus cache) for the first load, however, it does not solve the problem for bundled content that you would wish to load lazily... Unless, of course, multiple import maps were supported (they'd been removed for MVP) and allowed to be added after loading had started...

hiroshige-g commented 4 years ago

Can you still map identifiers to data URLs?

Yes.

multiple import maps were ... allowed to be added after loading had started

Currently I expect this is unlikely to happen (I haven't figure out how to achieve this in the spec/impl).

jakearchibald commented 4 years ago

I'm wondering if import maps can bring the same functionality to standard modules:

It will break any relative URLs inside the data url, since they'll become relative to the data url.