Contact emails
mk...@chromium.org, j...@chromium.org
Spec
http://w3c.github.io/webappsec/specs/subresourceintegrity/
Summary
Subresource Integrity defines a mechanism by which user agents may verify that a fetched resource has been delivered without unexpected manipulation. In a nutshell, metadata inlined into HTML elements allows the browser to determine whether the resource that was downloaded matches the resource the page's author expected to download.
Motivation
Websites are amalgams of resources loaded from a variety of sources, only some of which are under the control of the site's author. SRI allows an author the opportunity to lock her site down to a specific set of resources, mitigating the risk that (for instance) a compromised CDN server can execute malicious code on her site.
Compatibility Risk
The core of this spec is low-risk: there's real value in allowing authors to verify the integrity of resources they download, and if we can get the caching semantics right (from a security/privacy perspective), there might be solid performance wins.
Other aspects of the proposal (lowering the bar for mixed content warnings, for example), have generated a good deal of discussion (garment-rending, teeth-gnashing, eye-poking-outing, ...) from knowledgeable folks like Ryan and Chris, and will likely morph before implementation. CCing both here.
Implementation experience, behind a flag, will help us decide where to take the spec, and inform our decisions about what pieces we'd like to ship in the future.
Ongoing technical constraints
None.
Will this feature be supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?
Yes.
OWP launch tracking bug?
Link to entry on the feature dashboard
http://www.chromestatus.com/features/6183089948590080
Requesting approval to ship?
No. The goal here is simply to gain implementation experience in order to answer some of the key questions in the spec. For example, we need to decide exactly which set of bits we verify. Should we undo content/transport encoding before verification? How should we handle downloads? What about IFramed resources?
If things go well, we'll send a separate intent to ship when the spec is closer to CR.
-mike
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
It might be out-of-context for the discussion, but out of curiosity, how would data compression servers like the one here [1], would behave with respect to the SRI?If I understand correctly, these servers can transcode some of the contents (e.g. images) to optimize the bandwidth.
On Mon, Mar 24, 2014 at 9:44 AM, Vivek Galatage <viv...@chromium.org> wrote:
It might be out-of-context for the discussion, but out of curiosity, how would data compression servers like the one here [1], would behave with respect to the SRI?If I understand correctly, these servers can transcode some of the contents (e.g. images) to optimize the bandwidth.We're not able to distinguish "good" manipulation of a resource (compression), from "bad" manipulation (malicious replacement). Basically, an author's choice to use SRI means that she considers the integrity of the resource to be more important than its performance. We send `Cache-Control: no-transform` in order to express this preference.There will certainly be folks behind proxies that intentionally MitM their connections (corporate proxies are the best-case of this). The 'noncanonical-src' section of the spec <http://w3c.github.io/webappsec/specs/subresourceintegrity/#the-noncanonical-src-attribute-todo-1> allows for a fallback for the cases in which a resource is manipulated, if the author would like to offer such an alternative.
Relatedly, we've gotten a tiny bit of feedback from Akamai (second-hand, through mnot@) with a suggestion that we add a syntax that would make it easier for their services (and services like PageSpeed) to manipulate the expected hashes for resources served to pages which opt-in to their services. I expect we'll need something like that in the future, but it's not in the current draft.-mike
I haven't thought deeply about SRI. I find lots of your arguments fairly compelling, but would like to hear someone more versed in the counterarguments argue the case. Or maybe there's a link to the other side on the WG mailing list archive somewhere?Some thoughts:* Some of the performance concerns could be mitigated with a merkle tree, as agl@ has pointed out previously when we've discussed these ideas
* I think lots of the performance concerns apply to blindly using SRI everywhere. But one may want to be more selective. For example, maybe ensuring the integrity of jQuery loaded from the Google CDN. Script resources cannot be progressively processed, so IIUC the performance concern there seems less serious.
* It's true though, that providing an integrity attribute might be a performance footgun in many places.
Hi Ryan,
Responding to a few of the concerns you raise...
On 25 Mar 2014, at 6:43 am, Ryan Sleevi <rsl...@chromium.org> wrote:
[...]
> I think the proposal is actively performance-hostile, and as such, it's extremely unlikely to be adopted by those who would most benefit.How often does that happen? AIUI these proxies are either (a) imposed upon the user by a network, or (b) opted into through the UA, in which case the UA has the opportunity to make sure SRI doesn't interfere.
>
> - It's hostile to the user's performance choices, by actively preventing performance-enhancing transcoding proxy the user has opted in to.
> - It's hostile to operators' performance choices, because it creates an innate hostility for modules like mod_pagespeed (requiring them to rewrite/strip the headers)The folks that I talk to from products like that *want* to be doing this sort of thing. Have you asked the mod_pagespeed team what they want?
> - It's hostile to user agents' performance choices, because it actively prohibits processing content until integrity has been verified.This is indeed an issue.
Why? That seems like a very arbitrary limitation.
> For the sake of discussion of this spec, I think the discussions of benefits MUST EXCLUDE the mixed content discussion (listed under Section "1.2.3 Fallback" of the specification). That is, the merits of Sub-Resource Integrity must be on their own, without mixed content.
I'd like to see SRI change so that it's backwards-compatible for the mixed content case; e.g.,
> That said, the two concerns are:
> - It provides a false sense of security if delivered over HTTP [eg: can UAs ignore such directives for being the silliness they are, if the resources was over HTTP?]
<script src="https://cdn.google.com/jquery?whatever" sri-src="http://cdn.google.com/jquery?whatever" integrity="ni:..."></script>
That way, if the UA ignores SRI, they use the HTTPS URI, and don't have to worry about mixed content.
> - It can actively harm/degrade security if mixed content is permitted"Can" is different than "will." Can SRI be used in a way that degrades security? Sure, but there are lots of ways you can degrade security in the Web platform.
We address these sorts of things all of the time, through education, best practices, and sensible defaults.
Withholding tools from people out of this kind of concern just means that their use cases won't be met, and they'll hack the tools until they are, perhaps in other ways that degrade security. I know that many browser folk have a justifiably low estimation of the common users' (and even administrators') understanding of security, but I don't think making a Lowest Common Denominator Web is the right answer (either in security UI or capabilities).
> Given the above performance concerns, it seems highly unlikely that those most at risk / most likely to benefit from SRI (eg: large sites with large performance concerns) will opt-in.All of the conversations I'm having point to the opposite. Intelligently used, SRI helps get around a good deal of the pain with deploying TLS in the medium term, while we sort out the longer-term story of increasing the deployment of HTTPS.
[...]
> From reading the discussions, it seems that the most benefit/excitement from Sub-Resource Integrity comes from (a) those expecting UAs to permit mixed-content when SRI is used [Section 1.2.3] and (b) UAs to treat SRI as content-addressable-storage [Section 4], thus freeing caches from URIs.Without speaking for others - the browser folk outside of Chrome that I talk to are *much* less hostile to SRI, so I don't read the situation the same way.
>
> Both of these 'benefits' seem extremely security-hostile, and thus unlikely to be implemented, so I don't get as excited.
"or an extreme example, if you're concerned that https://cdn.google.com is compromised (or is just serving up content on behalf of the NSA), you can rest assured that the script/img/etc that you are looking for hasn't been swapped out from underneath you."
"This attribute (and fallback in general) only makes sense if we care about allowing cache-friendly (read “HTTP”) URLs to load in an HTTPS context without warnings. I’m not sure we do, so I’m not going to put too much thought into the details here before we discuss things a bit more. (mkwst)"
Hooray! This is an interesting enough feature to argue about. At length. :)First, let me try to be clear about what I intend this "intent" thread to cover:
- I intend to add support for an `integrity` attribute on a variety of HTML elements, which allows authors to specify integrity metadata for resources those elements fetch.
- I intend to add verification functionality somewhere TBD (probably in Blink, maybe in the network stack, maybe in Service Workers, maybe somewhere else entirely; active discussion with area experts was my main purpose in this thread) that uses the integrity metadata specified in #1 to block the execution or rendering of resources which fail an integrity check.
- I intend to add some sort of fallback functionality, similar to what's specified in the 'noncanonical-src' section; folks have convinced me that it's worth implementing even in the case where we entirely throw out the concept of relaxing mixed-content. This section of the spec is, as Ryan notes, under construction. I'll work on that this week to try to make the use case and value more clear (basically, I agree with Mark's suggestion).
- I would like to explore the possibilities of caching based on integrity metadata rather than URL. This would have real value in the generalized jQuery case (I think the network team did some experiments in this direction that Chris or Will might be able to detail) and given the mitigations outlined in the spec, I don't believe it's as much of a security footgun as Ryan and Chris seem to.
- Given that any integrity guarantee we could make depends entirely on our ability to trust the document which contains the integrity metadata, I think it's pretty reasonable to support integity checks _only_ for documents served over HTTPS. I think I'd be happy to hard-fail integrity checks if the document including metadata is served over HTTP.
think this would address Ryan's concern #1.- I, personally, am not terribly thrilled about the mixed-content portion of the spec. I understand that others are, I understand the potential value there and I do think we can make it work, but I share Ryan and Chris' general reluctance to change our behavior (though, obviously, not to the same extent :) ). In _this_ intent thread, however, I don't intend to make any change to Blink's mixed-content detection code. If a cosmic event happens, and the security team decides that that such a change is indeed worthwhile, I'd suggest that it should be covered by a separate intent. I think this addresses Ryan's concern #2 for the moment, but certainly lends strength to his suspicion that this proposal is a trojan horse.
With that as background, I think Ryan's suggestion to consider the value of theproposal without consideration of its potential effect on mixed-content isreasonable. So why should we do this?
- SRI offers authors the ability to reduce the ambient authority of CDNs and other third-parties. I want the benefits of Akamai's or Google's reach, but I don't want to _trust_ them further than I have to in order to gain those benefits. I want the exciting potential of some random third-party widget, and I'm happy for them to bear the hosting costs, but I don't trust them not to pull the rug out from under me. Contractual obligations are good, resource pinning is better.
- SRI enables content-based caching, which, if we're careful about it, has distinct advantages for performance. It's probably worth focusing some attention on the mitigations and risks outlined in the spec; if we're missing things there, help would be appreciated.
At what cost would we attain these benefits?
- Ryan, quite correctly, claims that the priority of constituencies obligates us to consider the user above site authors. I agree with this completely. I disagree, however, that making it more difficult for some kinds of transcoding proxies to operate violates this priority. If it did, I think we'd have to be more willing to weaken HTTPS in general, as that certainly has the same effect on proxies sitting between the user and the resources they wish to download.
We block proxies' ability to MitM connections by default, even if a user really wants that behavior. If a user (or the company she works for) wishes to negate the security guarantees of that behavior, we allow them to opt-out by adding a new root to the set locally trusted. Allowing an opt-out of SRI (perhaps by installing an extension which strips or modifies the integrity metadata) is similarly available.
- Performance impacts. I suspect that the advantage of not loading jQuery anew every time you hit a new website would be substantial. Would that, and similarly-shared resources outweigh the impact of delaying rendering/execution until the resource is loaded? Possibly. If we make progressive validation via merkle trees or similar is a 1.0 requirement rather than being something we can push out to the next version of the spec, we can mitigate this risk.
We don't have a syntax for that yet. We don't really have good ideas about how such a syntax should look. Suggestions welcome. :)*shrug* I think it's a very reasonable feature to experiment with/implement. With implementation experience and experimentation, we'll be able to make more informed decisions about _shipping_ when we get to a more stable state. That's how I'd like to proceed.
I tried to inline responses, but it ruined the numbering which came from formatting. So I'm top-posting instead. Sorry if this bothers anyone.
(2) From my perspective, were we to implement SRI, it's best not to do so in the network stack. It would lead to significant buffering requirements within the network stack. Our resource loading is flow controlled by being mostly pull-oriented (renderer pulls data from the network stack which pulls data from the network and opens up network receive windows to accept more data). If the network stack were to have to verify integrity before passing data onward to the consumer, that would increase its own buffering (and thus memory) requirements, which is more correctly delegated to the consumer.
(3) Just doublechecking, mnot's suggestion was about structuring the fallback so that user agents that don't implement noncanonical-src still work by loading from the src attribute, right? What's the reason for having the alternate src URI in the first place? The document mentions using a HTTP URI (to be "cache-friendly"), but I assume that's only if we wanted to relax our mixed content policy. But your comment suggests there is another reason. Can you explain that? It's not anywhere in these emails, or else I've missed it (sorry).
(4) Indeed, there is experimental data evaluating the potential gains of this approach. I need to go find it again. I forget the details, but I think they weren't that impressive. JQuery is often self-hosted and stripped down, so the hit rate is less than one might imagine. Let me confirm that though (I wish GMail search worked better). That said, the gains will often be in the long-tail where less experienced developers are unaware of Google Hosted Libraries or the advantages of self-hosting a stripped down version of jQuery. And I am increasingly more concerned about long tail performance.
I'm also concerned about the privacy implications here from being able to, compute a digest from a 3rd party origin's resource, and use that as the integrity metadata to see if that site has been visited before, without even necessarily visiting the website. I'm no privacy expert, so I defer to others as to whether or not this is a serious issue.
(1) I think missing in this explanation is that, even if you trust a CDN to be well-intentioned, it is still vulnerable to compromise. SRI would help mitigate that.
As others have pointed out, I'm worried that a number of middleware (transparent proxies, anti-virus software, data-loss prevention, etc) will manipulate the content and make it impossible to widely enforce SRI. But this won't be known until this is deployed and measured on a number of users. Could this API be enabled for a swath of users (with some services opting in), without going the fully-shipped route to measure this?
Alternately, would it make sense to do probes for some random content on the web inside of Chrome now and see how common manipulations are?
On Wed, Mar 26, 2014 at 12:51 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
I tried to inline responses, but it ruined the numbering which came from formatting. So I'm top-posting instead. Sorry if this bothers anyone.Sorry. I thought using GMail's formatting tools would make the email easier to read. I should have stuck to plain text.(2) From my perspective, were we to implement SRI, it's best not to do so in the network stack. It would lead to significant buffering requirements within the network stack. Our resource loading is flow controlled by being mostly pull-oriented (renderer pulls data from the network stack which pulls data from the network and opens up network receive windows to accept more data). If the network stack were to have to verify integrity before passing data onward to the consumer, that would increase its own buffering (and thus memory) requirements, which is more correctly delegated to the consumer.
That makes sense. I'd like to ensure that we don't end up writing validation code 80 times across the codebase, but we certainly don't need to do work in the network stack to make that possible.That said, the network stack is a nicely central place to do this kind of work. :) Would progressive hashing make you less concerned about the buffering requirements?
(3) Just doublechecking, mnot's suggestion was about structuring the fallback so that user agents that don't implement noncanonical-src still work by loading from the src attribute, right? What's the reason for having the alternate src URI in the first place? The document mentions using a HTTP URI (to be "cache-friendly"), but I assume that's only if we wanted to relax our mixed content policy. But your comment suggests there is another reason. Can you explain that? It's not anywhere in these emails, or else I've missed it (sorry).
In a nutshell, the current failure mode is to block the resource completely in cases where MitM proxies manipulate them. In cases of important scripts, this would result in breaking the site entirely.The suggestion, then, is to have a fallback mechanism which would not be integrity checked. Perhaps it would be hosted on the same server as the page itself; you wouldn't get the benefits of your globally awesome CDN, but you'd trust (at least) the source of the file. This would enable your application to function correctly in environments that would be otherwise entirely broken (Global MegaCorp with its draconian IT department, for example).
(4) Indeed, there is experimental data evaluating the potential gains of this approach. I need to go find it again. I forget the details, but I think they weren't that impressive. JQuery is often self-hosted and stripped down, so the hit rate is less than one might imagine. Let me confirm that though (I wish GMail search worked better). That said, the gains will often be in the long-tail where less experienced developers are unaware of Google Hosted Libraries or the advantages of self-hosting a stripped down version of jQuery. And I am increasingly more concerned about long tail performance.I'd love to see whatever data you've gathered in the past.
It's a bit chicken-and-egg, isn't it? Current best-practice creates conditions in which this kind of caching is less effective than it could be. For example, if content-based caching existed, developers might have more incentive to split out the libraries from the rest of their code, and to use The Canonical Version rather than stripping things down.
I'm also concerned about the privacy implications here from being able to, compute a digest from a 3rd party origin's resource, and use that as the integrity metadata to see if that site has been visited before, without even necessarily visiting the website. I'm no privacy expert, so I defer to others as to whether or not this is a serious issue.
This is certainly something to be concerned about. We try to mitigate the risk with the recommendations in http://w3c.github.io/webappsec/specs/subresourceintegrity/#recommendations-1 Suggestions for and critique of this section of the spec would be very much appreciated.
On Wed, Mar 26, 2014 at 6:38 AM, Mike West <mk...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 12:51 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
I tried to inline responses, but it ruined the numbering which came from formatting. So I'm top-posting instead. Sorry if this bothers anyone.Sorry. I thought using GMail's formatting tools would make the email easier to read. I should have stuck to plain text.(2) From my perspective, were we to implement SRI, it's best not to do so in the network stack. It would lead to significant buffering requirements within the network stack. Our resource loading is flow controlled by being mostly pull-oriented (renderer pulls data from the network stack which pulls data from the network and opens up network receive windows to accept more data). If the network stack were to have to verify integrity before passing data onward to the consumer, that would increase its own buffering (and thus memory) requirements, which is more correctly delegated to the consumer.
That makes sense. I'd like to ensure that we don't end up writing validation code 80 times across the codebase, but we certainly don't need to do work in the network stack to make that possible.That said, the network stack is a nicely central place to do this kind of work. :) Would progressive hashing make you less concerned about the buffering requirements?Only if it were mandatory and had well-defined limits on the amount of data that needs to be read before being able to do digest verification of a chunk and handing off a verified data chunk to the consumer.
I think that the network stack is the wrong place to do this due to this being primarily a web platform feature. We should implement this in the web resource loading part of our code instead. I suggest either doing it in the Blink loader or the Chromium browser-side multiprocess resource loader (ResourceDispatcherHost). This way, our other non-web network stack consumers don't get affected by this. Since the browser process is essentially our kernel, it's probably advisable not to do excessive buffering there. So I guess my overall recommendation is to implement in the Blink resource loader. Wait, I forgot that this needs to interact with SW. SW is opt-in on the part of the document, so perhaps SW should be allowed to ignore the integrity attribute. It's too early in the morning to think this completely through, and this gbus is giving me a headache. I'll think about this later, or likely someone else can figure it out.
(3) Just doublechecking, mnot's suggestion was about structuring the fallback so that user agents that don't implement noncanonical-src still work by loading from the src attribute, right? What's the reason for having the alternate src URI in the first place? The document mentions using a HTTP URI (to be "cache-friendly"), but I assume that's only if we wanted to relax our mixed content policy. But your comment suggests there is another reason. Can you explain that? It's not anywhere in these emails, or else I've missed it (sorry).
In a nutshell, the current failure mode is to block the resource completely in cases where MitM proxies manipulate them. In cases of important scripts, this would result in breaking the site entirely.The suggestion, then, is to have a fallback mechanism which would not be integrity checked. Perhaps it would be hosted on the same server as the page itself; you wouldn't get the benefits of your globally awesome CDN, but you'd trust (at least) the source of the file. This would enable your application to function correctly in environments that would be otherwise entirely broken (Global MegaCorp with its draconian IT department, for example).Thanks for the explanation. I believe this reason can be safely ignored because IIUC, we possess the facility at the browser to fail open WRT additional CA trust anchors. This is how we disable key pinning when additional CA trust anchors are present. My recommendation would be to disable the integrity check in these cases. I think the fallback would discourage adoption, since it is actively painful for users behind these MITM proxies. Of course, I hate these MITM proxies so maybe we should hurt folks behind them so they complain to their IT admins :P I kid...I kid...but only kinda.
(4) Indeed, there is experimental data evaluating the potential gains of this approach. I need to go find it again. I forget the details, but I think they weren't that impressive. JQuery is often self-hosted and stripped down, so the hit rate is less than one might imagine. Let me confirm that though (I wish GMail search worked better). That said, the gains will often be in the long-tail where less experienced developers are unaware of Google Hosted Libraries or the advantages of self-hosting a stripped down version of jQuery. And I am increasingly more concerned about long tail performance.I'd love to see whatever data you've gathered in the past.Turns out I would too. I went into GMail looking for this data, but have been unable to find much more than discussion with Steve Souders about how much of jQuery is hosted on Google Hosted Libraries. IIRC, I dropped by his and Ilya's office to chat with this about this, web perfy stuff in general, and the meaning of life, but there is no record of the actual substance of that chat, so I have no interesting data to share other than vague recollections which I think you can safely ignore. We can also /summon souders and igrigorik to see if they remember. But I think you're best off gathering data on your own.It's a bit chicken-and-egg, isn't it? Current best-practice creates conditions in which this kind of caching is less effective than it could be. For example, if content-based caching existed, developers might have more incentive to split out the libraries from the rest of their code, and to use The Canonical Version rather than stripping things down.That's only true if the primary thing you're looking to save is network byte transfer / time. But from a web perf standpoint, self-hosting can be better in *some* (don't generalize too much from this, despite my verbose explanation) situations because parsing a huge blob of jQuery rather than the stripped down individual module you need is significantly more computationally expensive, especially on mobile where it's a non-trivial portion of page load time. In mobile web perf, you have to balance all the local resources (CPU, disk I/O for caches, network, etc) since they're all potentially the bottleneck, so a pure caching win does not necessarily translate into better performance. Now, folks (jochen?) are looking at whether or not we can cache the v8 parsed script representation (the ASTs) to save on a lot of the CPU time, but we're not there yet, and it just adds more flexibility/variables into how to schedule work for optimal performance.I'm also concerned about the privacy implications here from being able to, compute a digest from a 3rd party origin's resource, and use that as the integrity metadata to see if that site has been visited before, without even necessarily visiting the website. I'm no privacy expert, so I defer to others as to whether or not this is a serious issue.
This is certainly something to be concerned about. We try to mitigate the risk with the recommendations in http://w3c.github.io/webappsec/specs/subresourceintegrity/#recommendations-1 Suggestions for and critique of this section of the spec would be very much appreciated.I missed this section in an earlier pass. I think the CORS restriction in particular mitigates this privacy concern greatly.
(1) I think missing in this explanation is that, even if you trust a CDN to be well-intentioned, it is still vulnerable to compromise. SRI would help mitigate that.I agree. We mention that in the spec, but I neglected to spell out that threat here.-mike
On Wed, Mar 26, 2014 at 9:45 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 6:38 AM, Mike West <mk...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 12:51 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
I tried to inline responses, but it ruined the numbering which came from formatting. So I'm top-posting instead. Sorry if this bothers anyone.Sorry. I thought using GMail's formatting tools would make the email easier to read. I should have stuck to plain text.(2) From my perspective, were we to implement SRI, it's best not to do so in the network stack. It would lead to significant buffering requirements within the network stack. Our resource loading is flow controlled by being mostly pull-oriented (renderer pulls data from the network stack which pulls data from the network and opens up network receive windows to accept more data). If the network stack were to have to verify integrity before passing data onward to the consumer, that would increase its own buffering (and thus memory) requirements, which is more correctly delegated to the consumer.
That makes sense. I'd like to ensure that we don't end up writing validation code 80 times across the codebase, but we certainly don't need to do work in the network stack to make that possible.That said, the network stack is a nicely central place to do this kind of work. :) Would progressive hashing make you less concerned about the buffering requirements?Only if it were mandatory and had well-defined limits on the amount of data that needs to be read before being able to do digest verification of a chunk and handing off a verified data chunk to the consumer.You don't digest chunks though (at least, there is still no incremental hashing). So you have to buffer the entire thing. Now, you don't *have* to keep it in memory - that is, you can update the digest in chunks while spooling to a file-backed cache entry - but this is something where, at whatever layer integrity metadata is integrated, *something* has to hold back all the data until things are verified.
I think that the network stack is the wrong place to do this due to this being primarily a web platform feature. We should implement this in the web resource loading part of our code instead. I suggest either doing it in the Blink loader or the Chromium browser-side multiprocess resource loader (ResourceDispatcherHost). This way, our other non-web network stack consumers don't get affected by this. Since the browser process is essentially our kernel, it's probably advisable not to do excessive buffering there. So I guess my overall recommendation is to implement in the Blink resource loader. Wait, I forgot that this needs to interact with SW. SW is opt-in on the part of the document, so perhaps SW should be allowed to ignore the integrity attribute. It's too early in the morning to think this completely through, and this gbus is giving me a headache. I'll think about this later, or likely someone else can figure it out.Yet another reason why I favour the explore by SW aspect - it's still very unclear, from reading the spec, how this is supposed to interplay with Extensions (whether "Cloud to Butt" style extensions or things like HTTPS Everywhere), how it's meant to interplay with Service Workers, and how it's meant to interplay with opt-in client features for transcoding.That's not to say these can't be solved, but I feel like the spec should be clearer here.
(3) Just doublechecking, mnot's suggestion was about structuring the fallback so that user agents that don't implement noncanonical-src still work by loading from the src attribute, right? What's the reason for having the alternate src URI in the first place? The document mentions using a HTTP URI (to be "cache-friendly"), but I assume that's only if we wanted to relax our mixed content policy. But your comment suggests there is another reason. Can you explain that? It's not anywhere in these emails, or else I've missed it (sorry).
In a nutshell, the current failure mode is to block the resource completely in cases where MitM proxies manipulate them. In cases of important scripts, this would result in breaking the site entirely.The suggestion, then, is to have a fallback mechanism which would not be integrity checked. Perhaps it would be hosted on the same server as the page itself; you wouldn't get the benefits of your globally awesome CDN, but you'd trust (at least) the source of the file. This would enable your application to function correctly in environments that would be otherwise entirely broken (Global MegaCorp with its draconian IT department, for example).Thanks for the explanation. I believe this reason can be safely ignored because IIUC, we possess the facility at the browser to fail open WRT additional CA trust anchors. This is how we disable key pinning when additional CA trust anchors are present. My recommendation would be to disable the integrity check in these cases. I think the fallback would discourage adoption, since it is actively painful for users behind these MITM proxies. Of course, I hate these MITM proxies so maybe we should hurt folks behind them so they complain to their IT admins :P I kid...I kid...but only kinda.I do not think we should be trying to apply heuristics like the "additional CA trust anchors" (which are far, far from perfect) here.
This again presumes we're doing the mixed-content path, which from talking with security, no one is really keen on, me especially. I'm especially concerned by this use case, because it seems to be combined with an attempt to retrofit "authentication" onto the "opportunistic obfuscation" proposals for HTTP.
I mean, we can discuss this in depth and figure out the whole security story, but my goal in continuing to try to defer this particular use case is to at the minimal set of functionality first - which the spec itself is happy to call out minimal - before we start making changes to the promises web browsers try to make to users today regarding privacy and integrity.(4) Indeed, there is experimental data evaluating the potential gains of this approach. I need to go find it again. I forget the details, but I think they weren't that impressive. JQuery is often self-hosted and stripped down, so the hit rate is less than one might imagine. Let me confirm that though (I wish GMail search worked better). That said, the gains will often be in the long-tail where less experienced developers are unaware of Google Hosted Libraries or the advantages of self-hosting a stripped down version of jQuery. And I am increasingly more concerned about long tail performance.I'd love to see whatever data you've gathered in the past.Turns out I would too. I went into GMail looking for this data, but have been unable to find much more than discussion with Steve Souders about how much of jQuery is hosted on Google Hosted Libraries. IIRC, I dropped by his and Ilya's office to chat with this about this, web perfy stuff in general, and the meaning of life, but there is no record of the actual substance of that chat, so I have no interesting data to share other than vague recollections which I think you can safely ignore. We can also /summon souders and igrigorik to see if they remember. But I think you're best off gathering data on your own.It's a bit chicken-and-egg, isn't it? Current best-practice creates conditions in which this kind of caching is less effective than it could be. For example, if content-based caching existed, developers might have more incentive to split out the libraries from the rest of their code, and to use The Canonical Version rather than stripping things down.That's only true if the primary thing you're looking to save is network byte transfer / time. But from a web perf standpoint, self-hosting can be better in *some* (don't generalize too much from this, despite my verbose explanation) situations because parsing a huge blob of jQuery rather than the stripped down individual module you need is significantly more computationally expensive, especially on mobile where it's a non-trivial portion of page load time. In mobile web perf, you have to balance all the local resources (CPU, disk I/O for caches, network, etc) since they're all potentially the bottleneck, so a pure caching win does not necessarily translate into better performance. Now, folks (jochen?) are looking at whether or not we can cache the v8 parsed script representation (the ASTs) to save on a lot of the CPU time, but we're not there yet, and it just adds more flexibility/variables into how to schedule work for optimal performance.I'm also concerned about the privacy implications here from being able to, compute a digest from a 3rd party origin's resource, and use that as the integrity metadata to see if that site has been visited before, without even necessarily visiting the website. I'm no privacy expert, so I defer to others as to whether or not this is a serious issue.
This is certainly something to be concerned about. We try to mitigate the risk with the recommendations in http://w3c.github.io/webappsec/specs/subresourceintegrity/#recommendations-1 Suggestions for and critique of this section of the spec would be very much appreciated.I missed this section in an earlier pass. I think the CORS restriction in particular mitigates this privacy concern greatly.I'm not sure I fully understand why you feel CORS reduces it. Is it because you believe not a lot of resources are wide-open with CORS like this?
I'm also not sold on the SHA-512 (why not SHA-256? Or SHA-384?) It doesn't feel like the spec really deals with the substance of the security concerns here.The goal of the attacker is to passively probe whether or not you have a given resource cached. The hash of the resource they are targeting is known. Thus the strength of the hash doesn't matter here.For example, couldn't I programmatically exploit this by creating an img with a .src of a Blob/Data URI, set the .integrity attribute to the hash of what I want to probe for, and then inject into the DOM? There is no network traffic, I can ensure the Blob URI doesn't match the integrity attribute (thus always fails). However, IF the user has the resource cached in the content-address cache, the resource embedding will succeed - thus revealing where the user had been.
(1) I think missing in this explanation is that, even if you trust a CDN to be well-intentioned, it is still vulnerable to compromise. SRI would help mitigate that.I agree. We mention that in the spec, but I neglected to spell out that threat here.-mikeAbsent both caching and mixed-content - both of which I think need more fleshing out - I'm quite mixed on the value here.
If it's a script you know about/control, you can obviously host it locally (eg: not on the CDN). As Will mentions, there are many times where doing so can actually *improve* performance, compared to just throwing the whole-dang-library together.If it's a script you don't control - which is commonly the case for the analytics scripts that seem to be the risk the editors' are concerned about - it implies that the CDN/analytics provider is versioning their resources, and that site operators can review these versions, and whitelist the hash. Except the CDNs aren't - they frequently change - and so instead we're just encouraging a more broken web. The further insult is that "broken web" is exactly a use case being striven for (The Section 1.2.1 "mashup" example)If anything, I expect CDNs/analytics would be *opposed* to this change - not because of the security benefits, but because of the massive support hurdles. My anecdata is that very few analytics firms (eg: http://w3c.github.io/webappsec/specs/subresourceintegrity/#use-cases-examples ) actually version their analytics scripts.
We should only do this if there are clear security (without sacrificing performance) wins or performance (without sacrificing security) wins. Of these, the only "Use Case" that strikes me as meeting the criteria of clear wins in *either* category is the "Injecting Active Content" analytics example, which arguably can be used to improve security. The rest seem social issues whose "real" solution is non-technical, or which require much further specification/review/discussion (mixed-content, caching).For the analytics case, it seems like if site operators *really* are concerned about that, there are other technical solutions- Moving the analytics 'dynamic' code to an iframe, communicated with via a static, non-CDN'd JS file in the main document- Hosting the analytics JS locally- Exploring the Service Worker route
On Wed, Mar 26, 2014 at 5:44 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 9:45 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 6:38 AM, Mike West <mk...@chromium.org> wrote:
On Wed, Mar 26, 2014 at 12:51 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
I tried to inline responses, but it ruined the numbering which came from formatting. So I'm top-posting instead. Sorry if this bothers anyone.Sorry. I thought using GMail's formatting tools would make the email easier to read. I should have stuck to plain text.(2) From my perspective, were we to implement SRI, it's best not to do so in the network stack. It would lead to significant buffering requirements within the network stack. Our resource loading is flow controlled by being mostly pull-oriented (renderer pulls data from the network stack which pulls data from the network and opens up network receive windows to accept more data). If the network stack were to have to verify integrity before passing data onward to the consumer, that would increase its own buffering (and thus memory) requirements, which is more correctly delegated to the consumer.
That makes sense. I'd like to ensure that we don't end up writing validation code 80 times across the codebase, but we certainly don't need to do work in the network stack to make that possible.That said, the network stack is a nicely central place to do this kind of work. :) Would progressive hashing make you less concerned about the buffering requirements?Only if it were mandatory and had well-defined limits on the amount of data that needs to be read before being able to do digest verification of a chunk and handing off a verified data chunk to the consumer.You don't digest chunks though (at least, there is still no incremental hashing). So you have to buffer the entire thing. Now, you don't *have* to keep it in memory - that is, you can update the digest in chunks while spooling to a file-backed cache entry - but this is something where, at whatever layer integrity metadata is integrated, *something* has to hold back all the data until things are verified.I indeed was implying the requirement of some form of incremental hashing, as we've previously mentioned many times.I think that the network stack is the wrong place to do this due to this being primarily a web platform feature. We should implement this in the web resource loading part of our code instead. I suggest either doing it in the Blink loader or the Chromium browser-side multiprocess resource loader (ResourceDispatcherHost). This way, our other non-web network stack consumers don't get affected by this. Since the browser process is essentially our kernel, it's probably advisable not to do excessive buffering there. So I guess my overall recommendation is to implement in the Blink resource loader. Wait, I forgot that this needs to interact with SW. SW is opt-in on the part of the document, so perhaps SW should be allowed to ignore the integrity attribute. It's too early in the morning to think this completely through, and this gbus is giving me a headache. I'll think about this later, or likely someone else can figure it out.Yet another reason why I favour the explore by SW aspect - it's still very unclear, from reading the spec, how this is supposed to interplay with Extensions (whether "Cloud to Butt" style extensions or things like HTTPS Everywhere), how it's meant to interplay with Service Workers, and how it's meant to interplay with opt-in client features for transcoding.That's not to say these can't be solved, but I feel like the spec should be clearer here.I don't think that's a reason to say an absolute "no", but it's a reason to say, "hold on, let's work this through first", which is the purpose of this email, AIUI.
(3) Just doublechecking, mnot's suggestion was about structuring the fallback so that user agents that don't implement noncanonical-src still work by loading from the src attribute, right? What's the reason for having the alternate src URI in the first place? The document mentions using a HTTP URI (to be "cache-friendly"), but I assume that's only if we wanted to relax our mixed content policy. But your comment suggests there is another reason. Can you explain that? It's not anywhere in these emails, or else I've missed it (sorry).
In a nutshell, the current failure mode is to block the resource completely in cases where MitM proxies manipulate them. In cases of important scripts, this would result in breaking the site entirely.The suggestion, then, is to have a fallback mechanism which would not be integrity checked. Perhaps it would be hosted on the same server as the page itself; you wouldn't get the benefits of your globally awesome CDN, but you'd trust (at least) the source of the file. This would enable your application to function correctly in environments that would be otherwise entirely broken (Global MegaCorp with its draconian IT department, for example).Thanks for the explanation. I believe this reason can be safely ignored because IIUC, we possess the facility at the browser to fail open WRT additional CA trust anchors. This is how we disable key pinning when additional CA trust anchors are present. My recommendation would be to disable the integrity check in these cases. I think the fallback would discourage adoption, since it is actively painful for users behind these MITM proxies. Of course, I hate these MITM proxies so maybe we should hurt folks behind them so they complain to their IT admins :P I kid...I kid...but only kinda.I do not think we should be trying to apply heuristics like the "additional CA trust anchors" (which are far, far from perfect) here.Don't they only have to be as accurate as they currently are for key pinning? If not, I'd like to understand why.This again presumes we're doing the mixed-content path, which from talking with security, no one is really keen on, me especially. I'm especially concerned by this use case, because it seems to be combined with an attempt to retrofit "authentication" onto the "opportunistic obfuscation" proposals for HTTP.Can you explain why this presumes the mixed-content path? I'm not excited about that either, so I'm curious why that is implied here. I don't think a fallback mechanism that isn't integrity checked has to be http:// instead. But I might have misunderstood as I'm rather new to this discussion.
I mean, we can discuss this in depth and figure out the whole security story, but my goal in continuing to try to defer this particular use case is to at the minimal set of functionality first - which the spec itself is happy to call out minimal - before we start making changes to the promises web browsers try to make to users today regarding privacy and integrity.
(4) Indeed, there is experimental data evaluating the potential gains of this approach. I need to go find it again. I forget the details, but I think they weren't that impressive. JQuery is often self-hosted and stripped down, so the hit rate is less than one might imagine. Let me confirm that though (I wish GMail search worked better). That said, the gains will often be in the long-tail where less experienced developers are unaware of Google Hosted Libraries or the advantages of self-hosting a stripped down version of jQuery. And I am increasingly more concerned about long tail performance.I'd love to see whatever data you've gathered in the past.Turns out I would too. I went into GMail looking for this data, but have been unable to find much more than discussion with Steve Souders about how much of jQuery is hosted on Google Hosted Libraries. IIRC, I dropped by his and Ilya's office to chat with this about this, web perfy stuff in general, and the meaning of life, but there is no record of the actual substance of that chat, so I have no interesting data to share other than vague recollections which I think you can safely ignore. We can also /summon souders and igrigorik to see if they remember. But I think you're best off gathering data on your own.It's a bit chicken-and-egg, isn't it? Current best-practice creates conditions in which this kind of caching is less effective than it could be. For example, if content-based caching existed, developers might have more incentive to split out the libraries from the rest of their code, and to use The Canonical Version rather than stripping things down.That's only true if the primary thing you're looking to save is network byte transfer / time. But from a web perf standpoint, self-hosting can be better in *some* (don't generalize too much from this, despite my verbose explanation) situations because parsing a huge blob of jQuery rather than the stripped down individual module you need is significantly more computationally expensive, especially on mobile where it's a non-trivial portion of page load time. In mobile web perf, you have to balance all the local resources (CPU, disk I/O for caches, network, etc) since they're all potentially the bottleneck, so a pure caching win does not necessarily translate into better performance. Now, folks (jochen?) are looking at whether or not we can cache the v8 parsed script representation (the ASTs) to save on a lot of the CPU time, but we're not there yet, and it just adds more flexibility/variables into how to schedule work for optimal performance.
I'm also concerned about the privacy implications here from being able to, compute a digest from a 3rd party origin's resource, and use that as the integrity metadata to see if that site has been visited before, without even necessarily visiting the website. I'm no privacy expert, so I defer to others as to whether or not this is a serious issue.
This is certainly something to be concerned about. We try to mitigate the risk with the recommendations in http://w3c.github.io/webappsec/specs/subresourceintegrity/#recommendations-1 Suggestions for and critique of this section of the spec would be very much appreciated.I missed this section in an earlier pass. I think the CORS restriction in particular mitigates this privacy concern greatly.I'm not sure I fully understand why you feel CORS reduces it. Is it because you believe not a lot of resources are wide-open with CORS like this?Joel pointed out to me that CORS headers are already used out in the while without the expectation that we'd add this semantic here. So yes, adding this additional policy semantic might be problematic. I had not previously considered that. But if we were talking about something that didn't already have existing use, I don't think it would be problematic, except potentially as a footgun. But if an origin server has to opt-in to allow their users to leak browsing history of that origin, that strikes me as a reasonable mitigation. But I do agree that it's problematic if we reuse a previous opt-in signal in a way that was not previously intended, thus breaking backwards compat with previous privacy expectations.I'm also not sold on the SHA-512 (why not SHA-256? Or SHA-384?) It doesn't feel like the spec really deals with the substance of the security concerns here.
The goal of the attacker is to passively probe whether or not you have a given resource cached. The hash of the resource they are targeting is known. Thus the strength of the hash doesn't matter here.For example, couldn't I programmatically exploit this by creating an img with a .src of a Blob/Data URI, set the .integrity attribute to the hash of what I want to probe for, and then inject into the DOM? There is no network traffic, I can ensure the Blob URI doesn't match the integrity attribute (thus always fails). However, IF the user has the resource cached in the content-address cache, the resource embedding will succeed - thus revealing where the user had been.
(1) I think missing in this explanation is that, even if you trust a CDN to be well-intentioned, it is still vulnerable to compromise. SRI would help mitigate that.I agree. We mention that in the spec, but I neglected to spell out that threat here.-mikeAbsent both caching and mixed-content - both of which I think need more fleshing out - I'm quite mixed on the value here.
If it's a script you know about/control, you can obviously host it locally (eg: not on the CDN). As Will mentions, there are many times where doing so can actually *improve* performance, compared to just throwing the whole-dang-library together.If it's a script you don't control - which is commonly the case for the analytics scripts that seem to be the risk the editors' are concerned about - it implies that the CDN/analytics provider is versioning their resources, and that site operators can review these versions, and whitelist the hash. Except the CDNs aren't - they frequently change - and so instead we're just encouraging a more broken web. The further insult is that "broken web" is exactly a use case being striven for (The Section 1.2.1 "mashup" example)
If anything, I expect CDNs/analytics would be *opposed* to this change - not because of the security benefits, but because of the massive support hurdles. My anecdata is that very few analytics firms (eg: http://w3c.github.io/webappsec/specs/subresourceintegrity/#use-cases-examples ) actually version their analytics scripts.We should only do this if there are clear security (without sacrificing performance) wins or performance (without sacrificing security) wins. Of these, the only "Use Case" that strikes me as meeting the criteria of clear wins in *either* category is the "Injecting Active Content" analytics example, which arguably can be used to improve security. The rest seem social issues whose "real" solution is non-technical, or which require much further specification/review/discussion (mixed-content, caching).
For the analytics case, it seems like if site operators *really* are concerned about that, there are other technical solutions- Moving the analytics 'dynamic' code to an iframe, communicated with via a static, non-CDN'd JS file in the main document- Hosting the analytics JS locally- Exploring the Service Worker routeYou've mentioned the analytics case a number of times. I agree with your analysis there. What do you think about the jQuery case? jQuery is indeed versioned on CDNs, like Google Hosted Libraries. It seems to me that there is a non-zero security win for integrity protecting jQuery to insulate against CDN compromise (or outright malicious behavior, of which I'm more skeptical). I don't know if I think this security win is big, but I think that the non-incremental integrity mechanism is fairly cheap.
Before diving into the detail, let's say that I modify the intent to implement to something super minimal. Based on the discussion here, it sounds like Will would be interested in (and Ryan wouldn't be actively against) the following:1. Add `integrity` attributes for a bunch of elements.2. Use those attributes to verify the resource before rendering it.3. Add a CSP directive to set the document's response to a verification failure (which I forgot to mention before, sorry).4. Nothing else.5. Certainly not touching mixed-content, fallback, caching, etc.6. No, really. None of that.7. I mean it.This would provide a mechanism for authors to opt-in to a security win of some unknown size (let's say it's _huge_, because that would make me feel better), at the cost of blocking rendering until the resource is validated. Implementing this subset would allow us to determine exactly what that performance impact is, and also allow us to determine whether any of this makes sense on the web as it exists today (see Chris' concerns about transcoding proxies).
WDYT?
If anything, I expect CDNs/analytics would be *opposed* to this change - not because of the security benefits, but because of the massive support hurdles. My anecdata is that very few analytics firms (eg: http://w3c.github.io/webappsec/specs/subresourceintegrity/#use-cases-examples ) actually version their analytics scripts.We should only do this if there are clear security (without sacrificing performance) wins or performance (without sacrificing security) wins. Of these, the only "Use Case" that strikes me as meeting the criteria of clear wins in *either* category is the "Injecting Active Content" analytics example, which arguably can be used to improve security. The rest seem social issues whose "real" solution is non-technical, or which require much further specification/review/discussion (mixed-content, caching).I'll attempt to summarize this in a way that makes my position sound better: "The core of the specification improves security by blocking unexpected active content, but I'm concerned about the performance impact, and think it might annoy analytics and widget providers. I'm very much against the mixed-content bits, and think that the caching bits need a lot more thought."Is that at all accurate?