Re: Preloading using JS instead of a tag

Collection.

> We, Google, had a discussion internally.

"We, Google" were actually "yoavweiss@google.com, jyasskin@google.com,
koto@google.com, and hayato@google.com".

It's certainly not something that represents Google's opinion.

On Fri, Sep 25, 2020 at 11:17 AM Hayato Ito <hayato@google.com> wrote:

> Let me send a short summary here:
>
> - We, Google, had a discussion internally.
> - We'll start an origin trial with <link rel=webbundle>, tentatively, as
> long as we don't find any further security concern. We'll update the
> explainer as well.
> - Our primary motivation for the origin trial is to measure the benefits
> of this feature, webbundle subresource loading, in terms of the
> performance. We collect performance data and feedback so that we can know
> whether this feature is really worth or not for the platform earlier.
> - <link rel=webbundle> is not a final decision. We continue to discuss
> which one is the best for the platform; <script type=webbundle>, <link
> rel=webbundle>, or any other ideas.
> - If you have any opinions, we'd really appreciate that!
>
> On Tue, Sep 22, 2020 at 4:11 AM Jeffrey Yasskin <jyasskin@google.com>
> wrote:
>
>> On Mon, Sep 21, 2020 at 7:53 AM Krzysztof Kotowicz <koto@google.com>
>> wrote:
>>
>>>
>>>
>>> On Fri, Sep 18, 2020 at 8:04 PM Jeffrey Yasskin <jyasskin@google.com>
>>> wrote:
>>>
>>>> On Fri, Sep 18, 2020 at 1:29 AM Krzysztof Kotowicz <koto@google.com>
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Fri, Sep 18, 2020 at 9:08 AM Hayato Ito <hayato@google.com> wrote:
>>>>>
>>>>>> Let me update the status.
>>>>>>
>>>>>> We are considering using <script> elements as a declarative form [1],
>>>>>> instead of <link> elements, to address security concerns.
>>>>>> However, before proceeding this way, we'd like to confirm one thing;
>>>>>> Can't we use <link> elements even if we limit subresources loaded from the
>>>>>> bundle only to the same-origin resources to the bundle's URL?
>>>>>>
>>>>>> Let me explain with an example:
>>>>>>
>>>>>> Suppose we have a bundle, "https://example.com/sub.wbn", which
>>>>>> includes the following three resources:
>>>>>> - https://example.com/a.png
>>>>>> - https://example.com/b.png
>>>>>> - https://other.com/c.png
>>>>>>
>>>>>> We use this bundle as follows:
>>>>>>
>>>>>> <link rel=webbundle href="https://example.com/sub.wbn"
>>>>>>       resources="https://example.com/a.png https://example.com/b.png
>>>>>> https://other.com/c.png">
>>>>>> <img src=https://example.com/a.png>
>>>>>> <img src=https://example.com/b.png>
>>>>>> <img src=https://other.com/c.png>
>>>>>>
>>>>>> In this case,
>>>>>> - We load a.png and b.png from the bundle because their origins,
>>>>>> https://example.com, are the same to the bundle's origin,
>>>>>> https://example.com.
>>>>>> - however, we don't load c.png from the bundle because its origin,
>>>>>> https://other.com, is different from the bundle's origin,
>>>>>> https://example.com.
>>>>>>
>>>>>> This means that a bundle is effectively used to package subresources
>>>>>> in the one same origin. The different origin subresources are unlikely to
>>>>>> be packaged in one bundle.
>>>>>>
>>>>>> Suppose that we limit subresource loading this way, does security
>>>>>> concerns still apply to the usage of <link> elements?
>>>>>>
>>>>>>
>>>>> Thanks for the update! I think there are still some security concerns
>>>>> remaining. The concerns are much smaller of course (and limiting to the
>>>>> origin is a smart idea!), but I worry that the risk is not really about the
>>>>> origins here, but rather about being able to change the content under a
>>>>> given URL (without, say, a service worker installation) on the embedding
>>>>> page. It "feels" like it should require a capability of injecting a script
>>>>> element to the embedder.
>>>>>
>>>>> To make sure I understand the setup correctly - in order to have a
>>>>> correct (i.e. able to replace the resources) bundle served from
>>>>> example.com, one needs to have the capability to serve anything under
>>>>> example.com (e.g. the TLS keys)? If the attacker needs to have
>>>>> anything less than that, then the potential attack is still possible for
>>>>> shared origins (e.g. https://foo.example/~alice/bundle.wbn could
>>>>> replace https://foo.example/~bob resources requested on another
>>>>> page). The shared origin is usually not an issue, as Alice can trivially
>>>>> XSS Bob, but here the attack (replacing the resources by injecting a
>>>>> <link>) is happening on _another_ page, e.g. a
>>>>> https://i.only.trust.bob.example/.
>>>>>
>>>>
>>>> As mentioned in
>>>> https://github.com/WICG/webpackage/issues/580#issuecomment-679473747,
>>>> we avoid this particular attack by adopting a path restriction similar to
>>>> the one Service Workers use. So, say there's a bundle at
>>>> https://foo.example/~alice/bundle.wbn. It contains the following
>>>> resources:
>>>>
>>>> 1) https://foo.example/~alice/bundle.wbn/script1.js (doesn't work on a
>>>> filesystem, but a web server could serve it)
>>>> 2) https://foo.example/~alice/script2.js
>>>> 3) https://foo.example/~bob/script3.js
>>>>
>>>> The current proposal says it's authoritative for (1) and (2) by
>>>> default, but needs a response header (similar to Service-Worker-Allowed) to
>>>> be authoritative for (3). We could make it authoritative for just (1) or
>>>> for nothing at all by default, and still allow the header to expand the
>>>> authoritative scope.
>>>>
>>>>
>>> Thanks for clarifying that! Glad to know that the attack was taked into
>>> consideration! I would still have somewhat better sleep if controlling
>>> which scripts run on a page (or blocking ones from running) required
>>> injecting a <script> node.
>>>
>>
>> Note that a `<link rel=preload href="the_script.js"
>> integrity="sha256-WrongValue">` also blocks the script from running. I
>> believe the new risk is around changing what scripts run if the bundled and
>> non-bundled scripts are different for some reason, maybe because one is
>> stale or a server allows the attacker to write new content into a directory
>> that contains (directly or indirectly) scripts.
>>
>> Jeffrey
>>
>>
>>> It just feels too powerful, and similar in capabilities to WICG import
>>> maps <https://github.com/WICG/import-maps>. I worry, perhaps too much,
>>> that we might be enabling future bugs through this, as that behavior is
>>> quite surprising. But that's not a hard NO at this point.
>>>
>>>
>>>> Jeffrey
>>>>
>>>>
>>>>> [1] POC CL:
>>>>>> https://chromium-review.googlesource.com/c/chromium/src/+/2402927
>>>>>>
>>>>>> On Mon, Aug 31, 2020 at 4:15 PM Hayato Ito <hayato@google.com> wrote:
>>>>>>
>>>>>>> Regarding <script> as a declarative form, It seems there is a
>>>>>>> similar proposal, <script type="importamap">.
>>>>>>>
>>>>>>> (copy/pasted from https://github.com/WICG/import-maps)
>>>>>>>
>>>>>>> <script type="importmap">
>>>>>>> {
>>>>>>>   "imports": {
>>>>>>>     "moment": "/node_modules/moment/src/moment.js",
>>>>>>>     "lodash": "/node_modules/lodash-es/lodash.js"
>>>>>>>   }
>>>>>>> }
>>>>>>> </script>
>>>>>>>
>>>>>>> We'll report back once we know the status of <script
>>>>>>> type="importmap">. We might learn from there.
>>>>>>>
>>>>>>> On Fri, Aug 28, 2020 at 10:55 PM Yoav Weiss <yoavweiss@google.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Krzysztof and I talked about this offline and reached some
>>>>>>>> conclusions:
>>>>>>>>
>>>>>>>>    - `<script>` seems like the right declarative home for this -
>>>>>>>>    to make sure it's defended against similarly to other XSS vectors
>>>>>>>>    - A declarative solution can still be racy if specified
>>>>>>>>    naively, and the processing model should make sure that it is not (e.g. by
>>>>>>>>    not loading the bundle if resources covered by it were already fetched)
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Aug 28, 2020 at 12:42 PM Krzysztof Kotowicz <
>>>>>>>> koto@google.com> wrote:
>>>>>>>>
>>>>>>>>> I understand that. My question is, are we actually avoiding races
>>>>>>>>> if we kept, say, link element?
>>>>>>>>>
>>>>>>>>> <script>
>>>>>>>>> document.head.appendChild(scriptWithBundleUrl);
>>>>>>>>> document.head.appendChild(webBundleLink);
>>>>>>>>> </script>
>>>>>>>>>
>>>>>>>>> On Fri, Aug 28, 2020 at 12:11 PM Yoav Weiss <yoavweiss@google.com>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Think of the following HTML, based on Hayato's example:
>>>>>>>>>> ```
>>>>>>>>>> <link rel=stylesheet href="https://www.example.com/unbundled.css
>>>>>>>>>> ">
>>>>>>>>>> <script>
>>>>>>>>>> document.webbundles.add({
>>>>>>>>>>   href: 'https://www.example.com/foo.wbn
>>>>>>>>>> <https://www.exmaple.com/foo.wbn>',
>>>>>>>>>>   resources: ['https://www.example.com/a.js
>>>>>>>>>> <https://www.exmaple.com/a.png>', 'https://www.example.com/b.css
>>>>>>>>>> <https://www.exmaple.com/b.css>', ...]
>>>>>>>>>> });
>>>>>>>>>> </script>
>>>>>>>>>> <link rel=stylesheet href="https://www.example.com/b.css">
>>>>>>>>>> <script src="https://www.example.com/a.js">
>>>>>>>>>> ```
>>>>>>>>>>
>>>>>>>>>> The browser (all browsers, in subtly different ways) would take
>>>>>>>>>> the HTML tokens, scan them and speculatively preload a.js and b.css based
>>>>>>>>>> on that, before executing the inline script (which is blocked on the style
>>>>>>>>>> above it).
>>>>>>>>>> Aside: I believe that even without the blocking "unbundled" style
>>>>>>>>>> the race would be often lost. May merit testing in the different browsers.
>>>>>>>>>>
>>>>>>>>>> While we could ask developers to not do that, and always trigger
>>>>>>>>>> request for bundled resources from JS, that would have significant
>>>>>>>>>> ergonomics, adoption and performance implications, and I'd much rather we
>>>>>>>>>> don't go that route.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Fri, Aug 28, 2020 at 12:01 PM Krzysztof Kotowicz <
>>>>>>>>>> koto@google.com> wrote:
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Aug 28, 2020 at 11:49 AM Yoav Weiss <
>>>>>>>>>>> yoavweiss@google.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> If we want WebBundles to fit into today's pages (which e.g.
>>>>>>>>>>>> include `<script src>` tags), we need an imperative mechanism to load them
>>>>>>>>>>>> and tell the browser about the resources they contain.
>>>>>>>>>>>> An imperative mechanism to load them would only be effective
>>>>>>>>>>>> for dynamically loaded resources, which are inherently slower to discover.
>>>>>>>>>>>> It would be a shame if we ended up encouraging that pattern.
>>>>>>>>>>>>
>>>>>>>>>>>> Would moving away from `<link>` to e.g. `<base>` (as Mike
>>>>>>>>>>>> suggested) or `<script type=bundle>` address your concerns?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I would prefer base or script, yes. But is the raciness problem
>>>>>>>>>>> solved, given that DOM is mutable from JS? That would need to be addressed
>>>>>>>>>>> anyhow if I understand correctly.
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Aug 28, 2020 at 11:33 AM Krzysztof Kotowicz <
>>>>>>>>>>>> koto@google.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> The DOM tree can also change dynamically. If the element that
>>>>>>>>>>>>> controls the bundle loading is inserted via JS, would that
>>>>>>>>>>>>> also affect raciness? If so, there's little way around it, short of
>>>>>>>>>>>>> ignoring the behavior when added dynamically (which might be surprising for
>>>>>>>>>>>>> authors).
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Fri, Aug 28, 2020 at 10:58 AM Yoav Weiss <
>>>>>>>>>>>>> yoavweiss@google.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> An imperative mechanism to load bundles would be inherently
>>>>>>>>>>>>>> racy - the preloadScanner would not be aware of it, and can kick off script
>>>>>>>>>>>>>> requests before their bundles are discovered.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> If `<link>` is a risky choice here, I'm fine with a different
>>>>>>>>>>>>>> tag to do the same. I have no strong opinion regarding what would be a good
>>>>>>>>>>>>>> alternative.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Fri, Aug 28, 2020 at 10:44 AM Mike West <mkwst@google.com>
>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I don't have a strong opinion about the mechanism, but I do
>>>>>>>>>>>>>>> think the risk ascribed to the `<link>` approach is real.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If declarative mechanisms are preferred, I wonder if an
>>>>>>>>>>>>>>> extension to `<base>` would be more appropriate here than an extension to
>>>>>>>>>>>>>>> `<link>`. `<base>` already affects resource loading across the page (in
>>>>>>>>>>>>>>> kinda terrible ways, but still!), and so already needs to be addressed by
>>>>>>>>>>>>>>> folks who aim to sanitize user input.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> It also is suggested to be invalid outside of `<head>`,
>>>>>>>>>>>>>>> which would be similarly helpful if browsers implemented that as a
>>>>>>>>>>>>>>> requirement; there doesn't seem to be a WPT for it, and Chromium at least
>>>>>>>>>>>>>>> would fail.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> -mike
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Fri, Aug 28, 2020 at 9:18 AM Hayato Ito <
>>>>>>>>>>>>>>> hayato@google.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Ryosuke. Thanks for sharing concerns.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm wondering if we have imperative JS APIs which
>>>>>>>>>>>>>>>> are *equivalent* to declarative one, some of the security concerns will be
>>>>>>>>>>>>>>>> addressed?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Imperative JS APIs can be something like:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> <script>
>>>>>>>>>>>>>>>> // Tentative ideas. API surfaces do not matter for now.
>>>>>>>>>>>>>>>> document.webbundles.add({
>>>>>>>>>>>>>>>>   href: 'https://www.exmaple.com/foo.wbn',
>>>>>>>>>>>>>>>>   resources: ['https://www.exmaple.com/a.png', '
>>>>>>>>>>>>>>>> https://www.exmaple.com/b.css', ...]
>>>>>>>>>>>>>>>> });
>>>>>>>>>>>>>>>> </script>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> # Then, UA will try to load 'https://www.exmaple.com/a.png'
>>>>>>>>>>>>>>>> (the same origin resource of the bundle) from the specified bundle, instead
>>>>>>>>>>>>>>>> of the network.
>>>>>>>>>>>>>>>> <img src='https://www.exmaple.com/a.png'>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Is my understanding correct?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Fri, Aug 28, 2020 at 2:30 PM Ryosuke Niwa <
>>>>>>>>>>>>>>>> rniwa@apple.com> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Aug 27, 2020, at 1:05 PM, Jeffrey Yasskin <
>>>>>>>>>>>>>>>>> jyasskin@google.com> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi Web Perf experts,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We're working
>>>>>>>>>>>>>>>>> <https://www.chromestatus.com/feature/5710618575241216>
>>>>>>>>>>>>>>>>> on using (unsigned) web bundles to help with preloading subresources. The
>>>>>>>>>>>>>>>>> current design is at
>>>>>>>>>>>>>>>>> https://github.com/WICG/webpackage/blob/master/explainers/subresource-loading.md,
>>>>>>>>>>>>>>>>> but roughly the idea is that a page would build a bundle of the
>>>>>>>>>>>>>>>>> subresources it intends to use and put a
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <link rel="webbundle" href="/the_bundle.wbn"
>>>>>>>>>>>>>>>>> scope="/resources">
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> with their other preloads (or one of several variations).
>>>>>>>>>>>>>>>>> After that,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> <script src="/resources/foo.js">
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> would find the version in the bundle instead of having to
>>>>>>>>>>>>>>>>> fetch it independently.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> This isn’t about preloading is it? This will actually
>>>>>>>>>>>>>>>>> affect the resource being used by that script element. preload doesn’t do
>>>>>>>>>>>>>>>>> that so this is a pretty different feature.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> In https://github.com/WICG/webpackage/issues/580,
>>>>>>>>>>>>>>>>> Krzysztof worries that adding any new way for a <link> tag to affect script
>>>>>>>>>>>>>>>>> loading is a security risk, because pages may not be as careful about
>>>>>>>>>>>>>>>>> preventing users from injecting <link> tags as they are about <script>
>>>>>>>>>>>>>>>>> tags. Instead, he suggests using a Javascript API to tell the browser to
>>>>>>>>>>>>>>>>> preload subresources using a bundle.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> That would be a pretty serious security risk. Putting all
>>>>>>>>>>>>>>>>> other objections against web packaging / web bundles aside, this will be a
>>>>>>>>>>>>>>>>> pretty big show stopper.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - R. Niwa
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Hayato
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> koto@ / Krzysztof Kotowicz / Google
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> koto@ / Krzysztof Kotowicz / Google
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> koto@ / Krzysztof Kotowicz / Google
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Hayato
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Hayato
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> koto@ / Krzysztof Kotowicz / Google
>>>>>
>>>>
>>>
>>> --
>>> koto@ / Krzysztof Kotowicz / Google
>>>
>>
>
> --
> Hayato
>


-- 
Hayato

Received on Friday, 25 September 2020 02:54:23 UTC