18 ms·
Do not let your CDN betray you: Use Subresource Integrity
- popasmurf 11y agoAbout a year or 2 ago I saw someone here on HN suggest doing this very thing. If my memory is correct, I think it was after jQuery's CDN once became compromised. [Edit] I think this was the discussion, just over a year ago! - https://news.ycombinator.com/item?id=8359223 https://news.ycombinator.com/item?id=8359223
- jimktrains2 11y agohttp://jimkeener.com/posts/http http://jimkeener.com/posts/http is my concept from 2013 (hash attribute) and I'm sure I'm not the first, either. It's an old idea and I'm _very_ glad to see someone doing it! EDIT: I just reread my post and there are some wonky ideas mixed in with (what I think are) decent ones. Sorry!
- travjones 11y agoMake sense. Subresource integrity looks very easy to implement for developers, but what about CDNs? Is it difficult for them to implement CORS?
- AdmiralAsshat 11y agoAs long as jQuery is compliant, I feel like you've probably covered 80% of all use cases on the web.
- bugmen0t 11y agoFor static resources, it's nothing more than sending this HTTP header "Acess-Control-Allow-Origins: *". We reached out to jQuery and code.jquery.com does this for a few months now.
- deleted 11y ago[deleted]
- theandrewbailey 11y agoMozilla docs: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity https://developer.mozilla.org/en-US/docs/Web/Security/Subres...
- Olap84 11y agoChrome already have this for your information: https://www.chromestatus.com/feature/6183089948590080 https://www.chromestatus.com/feature/6183089948590080
- thexa4 11y agoYou could probably make an addon that tries to fetch the data from IPFS instead of the CDN. Might be a nice way to bridge the existing web.
- goodells 11y agoThis was my first thought as well. Why go through the trouble of redundantly fetching a resource by URI and verifying its checksum when you could just use a system designed for this in the first place?
- allannienhuis 11y agoThanks for that reference. https://ipfs.io/ https://ipfs.io/ is very interesting!
- ikeboy 11y agoSubresource Integrity works on both HTTP and HTTPS. This seems like exactly the thing that they were talking about when they started depreciating http [0]. Does this mean they've changed their mind? [0] https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http/ https://blog.mozilla.org/security/2015/04/30/deprecating-non...
- dspillett 11y agoNo, it just means that this method works for both HTTPS and plain HTTP - they are not stating an opinion of either protocol here. If you are using HTTP then this would protect you from one class of problem, but it leaves all the other potential problems open if they are relevant to your content.
- peteretep 11y agoThis could have been used to stop the Github DDOS from China, if I'm understanding it correctly
- codedokode 11y agoNo. They injected code into some visitor analytics script (like GA) and those scripts are constantly updating so you cannot calculate and store the hash.
- bsder 11y agoWell, seems like a good reason to block scripts that are constantly updating, no? I suspect this is going to become a turbo AdBlock. If the original page doesn't sign the content, block it.
- vinceyuan 11y agoI guess so. GitHub hit by DDoS attack https://news.ycombinator.com/item?id=9275041 https://news.ycombinator.com/item?id=9275041
- cbr 11y agoNope: http://www.jefftk.com/p/sri-against-the-great-cannon http://www.jefftk.com/p/sri-against-the-great-cannon
- peterwaller 11y agoOnly if this feature had widespread adoption. And if the GFW doesn't replace the hashes in the original content.
- nateabele 11y ago> An important side note is that for Subresource Integrity to work, the CDN must support Cross-Origin Resource Sharing (CORS). So, an extra request per resource, in other words?
- betimsl 11y agoNo, it will just compare given hash to file.
- malft 11y agoAn extra header.
- tveita 11y agoCORS doesn't require preflight requests for simple GETs and POSTs, since you can always trigger those anyway. The browser can just do the request and check the headers on the response.
- nly 11y agoWouldn't doing this on POST be dangerous? POSTs are not expected to be idempotent, so you're trusting the server to understand and check the Origin header etc.
- codedokode 11y agoYou can send POST to any server using a JS-submitted form so it doesn't introduce new attack vector.
- malft 11y agoYou get slightly more power in that you can post malformed multipart stuff.
- dspillett 11y agoThis could also be used to remove the need for a CDN for common libraries like jquery and similar resources. If the browser knows it has a file in its cache with the same properties (has, size, name) even if it come from a different site it can be pretty sure that the content is the same so no new request is needed. So your site could use the cached copy of jquery (for instance) that was originally brought down to serve my site, or vice versa.
- sidarape 11y ago> size, name I don't see why it would be necessary to provide a name and a size. If the hash is the same, we can be pretty sure that's the same file.
- deleted 11y ago[deleted]
- lcswi 11y agoAn additional layer of security does not hurt. Forging a hash.collision at the exact same filesize is harder than an arbitrary size.
- emn13 11y agoThat's not really true. In fact, practical collision attacks vs. MD5 preserved the size - which if you think about it, makes sense. Unless a has function is utterly terrible, it's not unreasonable to assume it's easier to find a few correlated bits than it is to append bits. After all, to append bits you're going to need to somehow ensure that the internal fixed-size state of the hash algorithm cascades into the same state or nevertheless gives the same output, and since it's trivial to have a very, very high period state machine, that may mean appending huge numbers of bits. If safety were an argument you'd add an extra, unrelated hash function. E.g. even md5 is likely much harder to break if you also have the CRC32, even though CRC is a thoroughly insecure hash (and of course, you wouldn't use an insecure hash, now would you?)
- dccoolgai 11y agoOne thing about SRI that's also great - even beyond the security concerns with 3rd party scripts - is the benefit of stability. You know whoever controls the other end of the src attribute on your 3rd party <script> tag won't go changing things (even with the best of intentions) quietly that break your site. It's an out-and-out win and I hope all browsers support it soon.
- lsaferite 11y agoAny idea if there is a catchable event to detect an integrity check failure?
- bugmen0t 11y ago"On a failed integrity check, an error event is thrown. Developers wishing to provide a canonical fallback resource (e.g., a resource not served from a CDN, perhaps from a secondary, trusted, but slower source) can catch this error event and provide an appropriate handler to replace the failed resource with a different one." Source: https://w3c.github.io/webappsec/specs/subresourceintegrity/#handling-integrity-violations https://w3c.github.io/webappsec/specs/subresourceintegrity/#...
- cbsmith 11y agoJust have JavaScript code check for variables that would show up in the load, no?
- MichaelGG 11y agoI'd guess that the more annoying 3rd party scripts (looking at you, addthis) would simply tell people not to use this attribute as it will "break compatibility and hinder our ability to deploy critical, potentially security impacting, fixes". In fact, if I were a 3rd party script provider, I'd want to make sure people don't do this to my scripts if I haven't "opted in" to keeping compat (i.e. never modifying the content at a URL). In addition to what you say, it'll also happen in reverse: Well-meaning webmasters will add this tag to improve security, then end up with a broken site. I'd be surprised if 3rd party providers don't start intentionally adding a random byte on each request (or every hour or something) to make sure that webdevs don't take a dependency on the contents of their files.
- ff7c11 11y agoWhy is this better than the Content Security Policy header where you can specify a hash or the hash attribute on a script tag?
- sarciszewski 11y agoYou can enable it via editing HTML rather than altering the HTTP headers.
- detaro 11y agothat only works on inlined scripts, not on external references.
- Someone1234 11y agoI'm a big fan of CSP, but even I have to admit that the CSP is quite large/expensive for a HTTP header field. It might be different for other sites/stacks but on ours we deliver CSP at the whole site level, meaning it is delivered with every response we send. Script integrity is only sent when that specific script is used, and it means our workflow doesn't have to change to rewrite a HTTP header dynamically with each page (based on which scripts are or aren't on that specific page). I legitimately have no idea how I would implement CSP with hashes for the scripts on that specific page. It would require me to actually patch the software stack upstream. I do however know exactly how I'd use the integrity field on a script block and could implement it with just raw HTML. PS - Not to mention that few browsers support level 2: http://caniuse.com/#feat=contentsecuritypolicy2 http://caniuse.com/#feat=contentsecuritypolicy2
- codedokode 11y agoCSP header doesn't need to be added for every response, e.g. for images or JS files.
- betimsl 11y agoThough, I don't see why CDNs wouldn't replace the sha1 with sha1 of injected file.
- sarciszewski 11y agoThe CDN doesn't control the SHA1, your website does.
- rubbingalcohol 11y agoSome sites host their static HTML on a CDN too. Example: anyone who uses Cloudflare.
- codedokode 11y agoIf you use proxy server that terminates HTTPS connections you have to trust it. There is nothing you can do.
- rubbingalcohol 11y agoI was thinking the same thing. For this to work you'd have to not use a CDN to host the static HTML (or maybe a different CDN?) Otherwise, it would be trivial for someone already sophisticated enough to inject a malicious script to also change the hash. Incidentally, I always wonder about this for non-HTTPS sites that offer binary downloads and crypto hashes to verify the files. How can you be sure someone isn't MitM'ing you?
- killnine 11y agoSimple, yet seemingly effective. As long as the hash the browser is checking matches the hash the server produced, the only options to beat this that I see are hash collision and bypassing the mechanism.
- ape4 11y agoI like the concept but there will probably more failed integrity check because of procedural mess-ups than actual attacks.
- riquito 11y ago> An important side note is that for Subresource Integrity to work, the CDN must support Cross-Origin Resource Sharing (CORS). If the CDN doesn't support CORS and the browser does support subresource integrity, subresource integrity is ignored (bad, since an attacker can disable CORS before changing the js) or enforced, thus refusing to execute the js (good)?
- Alex3917 11y agoIf the CDN doesn't support CORS then presumably the user won't even get the script back, but if they do then the browser shouldn't execute it due to the lack of CORS authorization, regardless of the integrity issue.
- bugmen0t 11y agospec co-editor here. SRI returns false (i.e. non-matching integrity) for scripts (or stylesheets) that do not enable CORS and are not same-origin [1]. Otherwise, an attacker could just disable CORS to bypass SRI. flies away [1] https://w3c.github.io/webappsec/specs/subresourceintegrity/#does-response-match-metadatalist https://w3c.github.io/webappsec/specs/subresourceintegrity/#...
- kra34 11y agoWouldn't it be faster (browser being able to use resource) to just skip the CDN and host the resources yourself?
- deathanatos 11y agoNot necessarily. Take jQuery: many sites use it. If both sites A and B load it from a CDN, and I've already visited site A, then when I visit site B, jQuery is already in my cache: we might not even need to request it, despite never having been to site B before. However, traditionally, the CDN now controls the content of your JS, and could inject whatever they want into it. That's where this proposal comes in… (Of course, if it isn't in the cache, then you might need as much as a DNS lookup+TCP connect+a TLS handshake to another host… tradeoffs. HTTP/1.x is also limited to n connections to a DNS name at time, so you can parallelize requests by hosting across multiple domains, such as a CDN, but I find this argument less compelling.)
- codedokode 11y agoDifferent sites might use different versions of a library. Also the cache gets polluted very quickly because many sites add caching headers for every request and cache size is limited. If average page size is 500 Kb and jquery size is 30 Kb gzipped you do not save much by hosting is on a CDN. What you get is more DNS requests, more downtime when that server fails or stalls and give out data about your users. I think it is easier just to host everything on your own server.
- codeonfire 11y agoExactly, people are giving up fundamental security for very little free resources and a tiny, tiny one-off performance improvement. But, what people also don't seem to care about is that these CDN's are actually created to track both users and site traffic as well. No bank uses (or should be using) third party CDN's, but other sites seem to not care.
- chaitanya 11y agoToday, whenever any resource (script/stylesheet) on an HTTPS website loads from HTTP, the browser rightly warns the user about insecure content. But with SRI, it should be possible to send scripts, css, etc. over plain HTTP right? As long as the landing page is HTTPS, and the hash checks out, is there any reason for browsers to show a warning to users then?
- TorKlingberg 11y agoYou would loose privacy: A snooper could see exactly what you are downloading. It may not matter in most cases, but still not something browsers want to compromise. This exposes a general issue that sometimes you want data integrity but not privacy. With https it's all or nothing.
- chaitanya 11y agoYes that's the only thing I could think of -- loss of privacy. (On the other hand, thanks to SNI, its easier than ever for a snooper to know which website you are visiting even if its completely on HTTPS; so the loss of privacy by switching to plain HTTP here is only incremental).
- emn13 11y agoWhy require CORS? What good is that, here? If you're a malicious CDN, you'll just not support CORS and so no one can use this to protect themselves. If the CDN is benign but gets hacked, this just leaves the (unlikely but possible) option of the hackers breaking CORS, waiting for the inevitable "I guess I'll just disable SRI", and then altering the subresource. Requiring CORS simply makes security more difficult to achieve.
- bugmen0t 11y agoThe browser must not know the content (or the hash of the content) of files on your intranet (or any other domain that is not the one you are visiting right now.) See https://annevankesteren.nl/2015/02/same-origin-policy https://annevankesteren.nl/2015/02/same-origin-policy and http://w3c.github.io/webappsec/specs/subresourceintegrity/#cross-origin-data-leakage http://w3c.github.io/webappsec/specs/subresourceintegrity/#c...
- emn13 11y agoIf the hash functions are secure, the only way for this to leak information is if the attacker can make good guesses as to what the resource is a priori, and then use this to verify it. Fair enough, that's some information leakage, but it's certainly not easy to exploit. Normal cross-origin limitations still apply, so you'd need to get creative to even get the information in the first place, and if you can, it's not clear what this adds over a timing attack. I'm still a little skeptical such a heavy handed restriction is necessary to maintain the current level of security; but then again - why take the risk?
- progmal1 11y agoAt its face this looks like a good idea, but given the hassle of injecting the new checksum in the base file for every change I doubt it will be done by anyone but the most security conscious companies.
- Semiapies 11y agoSeems trivial. You go to the CDN page to get the script URL and right next to it is the hash. Maybe they have the whole tag for you to copy and paste.
- mapgrep 11y ago1. Not many people hand-write HTML tags these days, they tend to get generated at the level of apps like WordPress (which already has an SRI plugin) or frameworks like Rails (which can already do things like javascript_include_tag :application, integrity: true). 2. The people who do hand write HTML tags tend to be precisely the type of people who would go out of their way to generate an md5 checksum on the commandline, or write a script to post process their HTML files.
- codedokode 11y agoThat is absurd. To prevent malicious modifications and data leak you can just host code on your own server. Using free CDN (without SLA) you just increase your site downtime and get nothing in return (well except that company and NSA can now collect IPs, UAs and referers of your users). CDNs are used to optimize traffic cost but hosting just single JS library there won't save you much. Calculating hashes is bothersome and requires modification of an app so probably nobody is going to use it. I never use libraries hosted at free CDNs. EDIT: I cannot think of a scenario where this feature can be useful. EDIT 2: And you cannot use this feature for scripts like Google Analytics because they can be modified anytime.
- err4nt 11y agoIt's not just about CDN-hosted files, it's also a way to not execute untrusted JS. Let's say you have a high-traffic WordPress site with a dev environment. You might have a clean theme and know all your JS, but be using plugins other people have written. Using this it looks like you could put the hash in your markup and if their JavaScript code changed it wouldn't execute. For some people having that deadman's switch might be better than an always-execute policy on JS that you aren't writing yourself.
- codedokode 11y agoThere is CSP ( https://en.wikipedia.org/wiki/Content_Security_Policy https://en.wikipedia.org/wiki/Content_Security_Policy ) to protect againgst inclusion of unapproved third party scripts. Hash check won't help against malicious WP themes because they would not output integrity attribute into generated HTML.
- Kenji 11y agoYou are right in everything you say here. I don't know why you are downvoted. Cross-domain JavaScript is cancer and most if not all websites that follow this practice could do without it.
- ihsw 11y agoNext can we apply it to whole HTML documents (including iFrames)? Then malicious ISPs/malware/etc would be unable to inject their ad spam code.
- deathanatos 11y agoFor the main HTML document, what would prevent the ISP from simply changing the hash to include/account for the injected ad spam code?[1] (for iframes, I think this would work fine) [1]: I'm presuming you're not using TLS, because if you were, then TLS would do this and more.
- ihsw 11y agoNot a whole lot, TBH. It raises the bar though from blind injection, which I think is quite good.
- matt_heimer 11y agoThis works because you trust the HTML provider (as a source of a valid hash) but not the CDN. If you don't trust your ISP then getting trusted hashes becomes more interesting. You'd need an encrypted/unmodifiable connection to a 3rd party repository of hashes for HTTP content but that'd only work for shared identical content (like the stuff in a CDN). For personalized content (any website with a login) you need a personalized hash, an HTTPS response could have a header with a hash (RFC 3230: Instance Digests in HTTP) but you can only trust that if you trust HTTPS and if you trust HTTPS then what does the header really add? You probably need two ISPs or at least VPNs if you want to start detecting tampering by an ISP.
- ihsw 11y agoThe idea is to provide protection even in HTTP-only environments (as HTTP is enforced in some places). It would add overhead to verify hashes in the manner that you have mentioned but I think it's worth it.
- codedokode 11y agoYou can just use HTTPS for that.
- darkr 11y agoAny idea why SHA384 is used over SHA256? Presumably it's not for collision avoidance, and it's not like anyone's going to be hitting the maximum message size of SHA256 with anything stored in CDN.. Edit: So it seems that all of the main variants of the SHA-2 family must be supported[1], and the spec supports multiple hashes being presented at once. It's just that SHA-384 seems to be used in all of the examples I've seen so far. > Conformant user agents MUST support the SHA-256, SHA-384 and SHA-512 cryptographic hash functions for use as part of a request’s integrity metadata, and MAY support additional hash functions. > When a hash function is determined to be insecure, user agents SHOULD deprecate and eventually remove support for integrity validation using that hash function. User agents MAY check the validity of responses using a digest based on a deprecated function. 1: http://www.w3.org/TR/SRI/#cryptographic-hash-functions http://www.w3.org/TR/SRI/#cryptographic-hash-functions
- nolok 11y agoReading the second example, it doesn't, it supports at least both of those.
- AhtiK 11y agoIt could be that SHA384 is immune to length extension attacks, SHA256 is not.
- bugmen0t 11y agohttps://github.com/w3c/webappsec/issues/477 https://github.com/w3c/webappsec/issues/477
- joveian 11y agoIt doesn't look like anything new AFAICT. I don't think they ever recommended sha-256 for TOP SECRET documents and with a quick scan I didn't see any new discussion in fips-180-4 itself.
- neoCrimeLabs 11y agoPerhaps I'm missing something here, so the browser can check the integrity of the included scripts as such: <script ... integrity="sha384-..."> How will the browser confirm that the source HTML requesting script isn't modified by the CDN? Well known CDN services, such as CloudFlare, are known for modifying the HTML -- This is not uncommon.
- Sidnicious 11y agoThis is probably meant for pages where you serve the HTML, but JavaScript libraries and styles may come from a CDN.
- carsonreinke 11y agoI wonder about situations that is used with 3rd parties (such as Facebook) and how they could distribute changes.
- MichaelGG 11y agoI doubt Facebook or any third parties will find much benefit to this. They will just say that they will protect their own CDN. Otherwise they effectively kill their ability to update their scripts. In fact, I'd expect them to deliberately disable this by updating the script with a random byte every so often. If a site wants to pin a third party to a specific version, they'll need to copy the file themselves. Though I'm not sure if this can be detected and "fixed" by the script author. I've noticed that Stripe's js file logs a warning if it thinks it's being loaded from another domain.
- carsonreinke 11y agoI mean if the Subresource is common place, someone might do this with a third party. The spec does not seem to address this.
- Animats 11y agoI've been plugging subresource integrity for months on HN, and have been modded down for it. Now Mozilla says "Don't let your CDN betray you". I've called some CDNs "MITM-as-a-service". Pages which use this should detect subresource integrity fails and report them to both the browser user and a non-CDN logging machine. Subresource integrity should put a stop to CDNs and ISPs inserting ads and spyware, because if even a few major sites use subresource integrity, they'll get caught quickly and will suffer bad publicity. This encourages using a CDN for only the bulky parts of a site. Put the important pages (entry pages, login pages, credit card acceptance) on a server you control, with your own SSL cert. Put the resources loaded with subresource integrity on a CDN. Now you're not trusting the CDN at all. Tools for website maintenance will need some improvement. Files need version info in their names; if the content changes, the URL should change, too. Maybe use the hash as part of the URL. Such files can have indefinite cache expiration times; they're immutable.
- joveian 11y agoHopefully it will soon be possible to use this for software downloads even if the files themselves are served over http or ftp (including, sadly, many open source projects; the thing I like best about the popularity of github is that you know you can clone over https). It is depressing how much software can be downloaded from any of dozens of mirrors without a hash anywhere (unless your antivirus software checks hashes of such downloads, which it sounds like many on Windows do). Of course, these sites could already have an https page with hashes for manual checking but almost never do. Hopefully automated checking would convince a few to do it. P.S. Blake2s would be a great additonal hash to support.
- ycitera 11y agoor just don't use CDNs... they are just another privacy issue on top of all other problems...
- z3t4 11y agoI think it's just better to download the files and host them yourself. The only reason why you want to include third party scripts is that you want automatic bug updates etc!?
- jszymborski 11y agoI have to disagree. Typically, having a 3rd party CDN hosted library like jQuery change on you is most definetly un-expected behaviour and not desired. The main purpose for CDN hosted scripts is allowing them to be cached in your browser, reducing latency via close edge servers and load times across website via caching. This proposal prevents malicious changes, as well cache poisoning, which was a very scary threat up until this announcement due to attack vectors like the one described in this defcon talk: https://www.youtube.com/watch?v=kLt_uqSCEUA https://www.youtube.com/watch?v=kLt_uqSCEUA (PDF slides here: https://defcon.org/images/defcon-20/dc-20-presentations/Alonso-Sur/DEFCON-20-Alonso-Sur-Owning-Bad-Guys-Using-JavaScript-Botnet.pdf https://defcon.org/images/defcon-20/dc-20-presentations/Alon...)
- z3t4 11y agoFair enough. Add httpS to that and it will be a good security layer.
- simoncion 11y ago> The main purpose for CDN hosted scripts is allowing them to be cached in your browser... Hopefully, subresource integrity schemes will eventually allow browsers to fetch from local cache based on the checksum of the file contents, rather than the URI from which the resource is served. :)
- jszymborski 11y agoThis is absolutely excellent! I always hold off on using 3rd party hosted scripts when feasible, but this'll change things for sure! Congratulations Mozilla!!! This is one of the few recent changes I've seen to browsers that fundamentally changes web-page security in a simple and novel way.
- nly 11y agoGreat! Now if only we can get asymmetric document signing going, including a "must be signed" header to compliment HSTS... SRI does little for trust when your CDN is also proxy-caching your HTML (e.g. Cloudflare).
- nodesocket 11y agoHere is a nice node.js package to generate a SRI from a file. https://www.npmjs.com/package/node-sri https://www.npmjs.com/package/node-sri
- Ellipsis753 11y agoI still don't really understand why we can't just run any files in cache (from other sites) with the same hash. If I have the sha-256 of an exe file, I'm perfectly happy to run any exe file with the same sha256 simply because collisions don't happen. Why is this different for JavaScript? If an attacker can inject HTML script tags into your website haven't you already lost?
- airza 11y agoContent security policy is a defensive technology which makes the answer to your last question "no." Attackers still need to have their script appear to execute from a whitelisted domain, which is only possible if the system you propose is enacted. IE - have your own random webpage which loads a script with hash X, then redirect to an XSS hole which appears to load that script on a client's site that also comes from a whitelisted domain. Since it is cached from the first site, it will be loaded as if it was hosted on the second site and thus bypass CSP.
- kazinator 11y agoOr, here is another idea: host the Javascript you need in your own damn domain!