
Do not let your CDN betray you: use subresource integrity (2015) - handpickednames
https://hacks.mozilla.org/2015/09/subresource-integrity-in-firefox-43/
======
AdamN
"The security properties of a collision resistant hash function, ensure that a
modification results in a very different hash."

I really appreciate the clarity of this post. The author is building up the
groundwork without skipping steps that may be obvious to many readers. I of
course knew the purpose of a hash before reading the article, but some people
don't - and that sentence clearly let those users know why the hash matters
without making it less readable for knowledgeable readers.

Writing clarity matters.

~~~
default-kramer
Honestly, I thought this line wasn't very clear, at least if I understand it
correctly. It is not important that modification produces a "very" different
hash, even a minimally different hash is still different enough. What is
important is that it is computationally infeasible to generate a collision. So
if your evil plan is to modify someone's .js file and then play with
comments/whitespace until the hashes match, you and the website will both be
dead before you find the collision.

~~~
braveo
no, it be "very different" means you can't do things like generate a hash of
all dictionary entries and identify when someone has a password that's only a
slight change from a known dictionary entry.

It's absolutely important in the security of hashes.

~~~
bartl
It's very important in the storage of hashed passwords, but not in checking
the integrity of files, which is the use case here.

------
Klathmon
If you use webpack, just drop in webpack-subresource-integrity [0] for
basically "free" SRI tags on all scripts.

It's not really as useful if you are serving your static assets from the same
place as the HTML (and you always use HTTPS) but if you load your js/css on
another server SRI can still provide some protection.

[0] [https://github.com/waysact/webpack-subresource-
integrity](https://github.com/waysact/webpack-subresource-integrity)

~~~
CraftThatBlock
And IIRC, it's built-in to creat-react-app.

~~~
julian37
It used to be, briefly, unfortunately it had to be removed again because
create-react-app has a zero-configuration policy and SRI can break pages
served without TLS unless Cache-Control: no-transform is set on the server
[1].

[1] [https://github.com/waysact/webpack-subresource-
integrity#pro...](https://github.com/waysact/webpack-subresource-
integrity#proxies)

------
yeldarb
It'd be cool if the browser used this to allow cross-origin caching as well.

Say I have jQuery previously loaded a page that included jQuery from CDNJS and
now I'm in China and another site tries to load jQuery from Google's CDN.

Currently that request would get blocked by the great firewall. But since the
browser should know that this file matches one it has seen (and cached) before
it should be able to just serve the cached file.

This could also save a network request even if I'm linking to a self-hosted
file on my own servers if I include the hash.

~~~
problems
The potential problem I see with this is that it could be abused for a "have
you loaded this resource" privacy leak. Simply pick a unique script on a
website, if my server doesn't get a hit then I know you went there before.

~~~
zrm
Possible solution is to have a content hash proxy trusted by the user but
shared between multiple users. Then the site can only get the data at the
proxy-level rather than the user-level, and not even that if the proxy is
large enough to justify crawling the web to pre-cache everything, or is behind
a larger cache that does.

~~~
nothrabannosir
That's not a solution but a work-around. The original privacy issue stands.
browsers can't cache hashed content by default. :/

~~~
zrm
The browser would know if it had a content hash proxy configured and then
could use it for all content hashed data. The issue becomes getting people to
use one, but partial uptake is better than nothing. You could at least get
most corporate and education environments with some equivalent to WPAD[1], and
maybe even some consumer-level ISPs the same way if they want to reduce the
traffic over their network.

[1] [https://en.wikipedia.org/wiki/Web_Proxy_Auto-
Discovery_Proto...](https://en.wikipedia.org/wiki/Web_Proxy_Auto-
Discovery_Protocol)

------
ejcx
Not just CDN, there's benefits to rolling out SRI for lots of your third
parties.

Your stripe js, scary ad networks js, front-end analytics companies. SRI is
really neat and helps protect yourself from these many 3rd parties being
pwned.

~~~
hdhzy
SRI may be a double edged sword. What if stripe fixes a bug and rolls a new
version of their JS? Your page stops accepting payments. That's bad.

If jQuery is compromised you'll detect it and download from different location
but for stripe there is no fallback.

~~~
cryptarch
Well, if Stripe wants you to stop accepting payments, you will. They already
can take the resource offline, I don't see how this is a new/additional
problem.

If they want you to stay up-to-date, they'll provide a piece of PHP/Node that
emits the latest URL/SRI tag.

~~~
LukeShu
You, as the web developer, want to start using subresource-integrity. Stripe,
as a depended-upon 3rd party, has not yet bought in to subresource-integrity
hype-train.

Stripe rolls out a fix for a security issue or other bug in their JS. This
breaks your subresource-integrity check. The didn't want you to stop accepting
payments, they wanted to fix a vuln.

That hampers the usefulness of using subresource-integrity on 3rd-party
resources _today_ (which is what yeldarb suggested). Perhaps in the future the
3rd party would provide a script that emits the URL/SRI, but that isn't today.

~~~
jffry

      the 3rd party would provide a script that emits the URL/SRI
    

And we're back to square one - we can't trust _that_ script to not get pwned

~~~
cryptarch
Not really, isn't packaging and securely distributing PHP/Node.js libraries a
solved problem?

~~~
johncolanduoni
If you're not updating the PHP/Node.js library, and you're not updating any
data you give it, where does it get the information it needs to update the
URL/SRI tag?

And if you are doing any of those things when Stripe pushes an update, how is
it any different that having to update the URL/SRI tag?

------
theandrewbailey
See also Content-Security-Policy require-sri-for

[https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Co...](https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for)

~~~
dane-pgp
By combining this with an extended form of SRI that supports hashes signed by
a private key, it would be possible to bring the security model of web apps
almost up to the level of desktop apps. You might still have to Trust On First
Use whatever key/identity was signing a given version of a web app (at least
the client-side component of it) but a browser could ask you "Do you want to
update to version X.Y of this web app?" before running any JavaScript that you
might want to check the release notes or reviews for first.

Ideally this would be combined with something like Binary Transparency, where
the new version has to have appeared in a public log for some time, and with
no trusted third parties publishing a "Do not trust version X.Y" warning in
another public log, acting as a sort of distributed immune system for the web.

------
recursive
"An important side note is that for Subresource Integrity to work, the CDN
must support Cross-Origin Resource Sharing (CORS)."

This doesn't make sense to me. Why shouldn't I be able to perform integrity
checking on resources from non-CORS domains?

~~~
epriest
Attackers could otherwise verify that resources on private networks or
retrievable only with the victim's cookies have certain content.

See, e.g.,
<[https://github.com/w3c/webappsec/issues/418>](https://github.com/w3c/webappsec/issues/418>)
for some broader discussion.

~~~
LethargicStud
Thanks for the link, but the closing '>' should not be part of it.

~~~
bzbarsky
That's a bug in ycombinator's linkification code. A quite frustrating one,
since <> is _the_ standard way to delimit URLs in plaintext (going back to
earlier than section 2.2 of RFC 1738, back in 1994!), so having linkifiers
that still fail to respect it is really unfortunate.

~~~
wilg
Is there a reason to delimit a URL in plaintext? I can't recall ever seeing
this syntax before and I don't really see a need for it.

~~~
bzbarsky
Yes, there is. Consider a URL followed by punctuation. How do you tell whether
that comma, period, question mark, etc should be included in the URL or not?
Had I put in a link to
[https://www.ietf.org/rfc/rfc1738.txt](https://www.ietf.org/rfc/rfc1738.txt)
in my original comment instead of "RFC 1738", there would have been a comma
right after the URL, for example.

The possible solutions to this punctuation-following-URL problem are that you
delimit the URL, contort your sentence so the URL is followed by a space and
some other words instead of punctuation, start adding random whitespace after
the URL but before the punctuation to avoid the linkifier eating the
punctuation, or stop putting URLs in plaintext. I've seen all of these used;
the first solution is by far the best.

Oh, and that's all from a Western perspective. If, on the other hand, you're
using a language that does not use space-separated words (e.g. a number of
East Asian languages), then delimiting becomes even more important, because
you can't just guess that the URL ends at the space character; there are no
space characters around.

I can't speak to your experience seeing or not seeing this syntax, but as I
said it's been part of the URL RFCs for over two decades, is used in other
RFCs where URLs can appear (e.g. the Link header syntax), and is reasonably
commonly used by people who both put URLs in their email and want to punctuate
it properly. I will grant that proper punctuation is out of fashion in certain
demographic groups. As is writing plaintext, I guess.

------
forgotpwtomain
This might have been mentioned somewhere else but - will browsers remove or
make an exception instead of blocking mixed-content[0] when a sub-resource
integrity check is present? I mean there really is no reason to be paying the
TLS over-head for commonly used libraries.

[0] [https://developer.mozilla.org/en-
US/docs/Web/Security/Mixed_...](https://developer.mozilla.org/en-
US/docs/Web/Security/Mixed_content)

~~~
Klathmon
Integrity is only 1/3 of the major benefits of TLS.

The other 2 (privacy and authentication) are very important as well and for
many are the main reason TLS is wanted.

~~~
forgotpwtomain
Do you care about privacy and authentication when downloading react.js from a
CDN?

~~~
Klathmon
You might not, but some may. Others still may care about keeping their ISP or
the public WiFi they are on from seeing they are downloading some scripts from
CDNs. Things like that are great for fingerprinting (only 2 sites happen to
use these 6 scripts with these specific versions, so if someone downloads
those they are on one of those sites).

Plus it still leaks tons of data in the headers. Request time, cache length,
useragent, cookies (maybe, hopefully not), accept-* headers, if modified since
leaking the last download time, and possibly a lot more.

------
depr
And get all your resources requested twice on Chrome:
[https://bugs.chromium.org/p/chromium/issues/detail?id=677022](https://bugs.chromium.org/p/chromium/issues/detail?id=677022)

~~~
labster
Well, that sounds twice as secure!

------
arghwhat
This only helps for JavaScript (and soon CSS) resources.

If your HTML goes through a CDN (say, you use the full Cloudflare package),
the CDN can of course just remove or modify these integrity attributes, or add
new scripts altogether.

------
nighthawk454
Looks like it has good support in Firefox and Chrome, but none in IE/Safari.

[http://caniuse.com/#feat=subresource-
integrity](http://caniuse.com/#feat=subresource-integrity)

------
vog
The title should have a "(2015)" suffix.

~~~
throwaway2048
Date tags are only relevant when the information they contain is of a time
sensitive nature. This article would say exactly the same thing if it was
written today.

~~~
elgenie
Someone who reads the title and thinks "Hmm, this new article sounds like that
Mozilla security engineer's article from a few years ago" would still
appreciate the date tag.

------
gszathmari
This tool lets you quickly assess whether third-party assets are protected by
SRI: [https://sritest.io/](https://sritest.io/)

Disclaimer: I am the developer of sritest

------
awqrre
or even better, avoid CDNs? it might even be cheaper when you account for the
extra work... and faster when you don't have to load data from 10 servers to
load just 1 web page

------
tofflos
Previous discussion:
[https://news.ycombinator.com/item?id=10310594](https://news.ycombinator.com/item?id=10310594)

------
zitterbewegung
I wonder if it would be a good idea that if the SRI detected a modified
javascript file that a warning should be presented to a web user when this
occurs?

~~~
icebraining
What would the user do with that information?

------
nwmcsween
It would be infinitely better if I could use a small hash instead of the giant
sha variants, imagine 40 or so resources x sha-x length.

~~~
dlss
There's no point in using a hashing algorithm that can be maliciously
collided.

------
homakov
SRI shouldn't use static hashes, it should set pub keys of different people
and the response must have N/M signatures. This way updates are possible and
you know N people confirmed the source as safe.

------
sedatk
fyi, Edge and Safari has yet to support this feature.

