- From: Jeffrey Yasskin <jyasskin@google.com>
- Date: Fri, 18 Sep 2020 11:04:29 -0700
- To: Krzysztof Kotowicz <koto@google.com>
- Cc: Hayato Ito <hayato@google.com>, Yoav Weiss <yoavweiss@google.com>, Mike West <mkwst@google.com>, Ryosuke Niwa <rniwa@apple.com>, public-web-perf <public-web-perf@w3.org>
- Message-ID: <CANh-dXnq2vjM6t4W9jN16SrQcpNsp+hKXrE1kreFf_KmVhUGGg@mail.gmail.com>
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. 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 >
Received on Friday, 18 September 2020 18:04:55 UTC