Re: Preloading using JS instead of a tag

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
>

Received on Monday, 21 September 2020 19:12:02 UTC