- From: Krzysztof Kotowicz <koto@google.com>
- Date: Mon, 21 Sep 2020 16:53:22 +0200
- To: Jeffrey Yasskin <jyasskin@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: <CAJCw+vsjmhF7um8QBGLB4ByrpODjOgcjPhuLQyJ1Wd9eCoWxvQ@mail.gmail.com>
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. 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 14:53:51 UTC