Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make sure that my JavaScript files delivered over a CDN are not altered?

I am working on a scenario in which some JavaScript files are to be hosted on a CDN. I want to have some mechanism so that when these file are downloaded on user side, I can ensure that the files were not tampered with and are indeed coming from the specified CDN.

I understand that the task is very easy if I am using SSL, but still, I want to ensure that the right files are served even on HTTP without SSL.

As far as I could search, there is no existing mechanism like digital signature for JavaScript files which is supported across platforms. Perhaps it's not needed?

Is there some method built in to browsers to verify the author of the JavaScript files? Is there anything I can do to do this in a secure way?

like image 811
baba26 Avatar asked Aug 01 '16 14:08

baba26


3 Answers

As a matter of fact, a feature like this is currently being drafted under the name of Subresource Integrity. Look into the integrity attribute of the <script> tag. While not yet fully adopted across the board, it fulfills just this purpose.

integrity

Contains inline metadata that a user agent can use to verify that a fetched resource has been delivered free of unexpected manipulation. See Subresource Integrity.

Source

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched file must match.

Source


Example:

<script src="https://example.com/example-framework.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    crossorigin="anonymous"></script>

Note however that this will not protect you against Man in the Middle attacks if you are transferring your resources via plain HTTP. In this case, the hash code can be spoofed by the attacker, rendering the defense against manipulated script files useless.

For this reason, you should always use secure HTTPS connections instead of plain HTTP in addition to the security measures described above.

like image 149
TimoStaudinger Avatar answered Oct 19 '22 07:10

TimoStaudinger


You're looking for subresource integrity checks.

For example, here's the jQuery CDN snippet:

<script src="https://code.jquery.com/jquery-3.1.0.js"
        integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
        crossorigin="anonymous"></script>
like image 36
Brian Avatar answered Oct 19 '22 07:10

Brian


Disclaimer: As always, you should only consider these mechanisms to be of any use when using https, as they can easily be disabled via MitM with http

In addition to the mechanism in the above answers, you can also use the content-security policy http response headers on the parent page.

http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

There are a few things to note here. The sha*- prefix specifies the algorithm used to generate the hash. In the example above, sha256- is used. CSP also supports sha384- and sha512-. When generating the hash do not include the tags. Also capitalization and whitespace matter, including leading or trailing whitespace.

Using Chrome 40 or later you can open DevTools then reload your page. The Console tab will contain error messages with the correct sha256 hash for each of your inline scripts.

This mechanism has been around for quite some time, so the browser support is likely pretty good, just be sure to check.

Additionally, if you want to ensure that older non-compliant browsers are not insecure, you can include a synchronous redirect script at the top of the page that is not allowed by the policy.

like image 6
Fabio Beltramini Avatar answered Oct 19 '22 05:10

Fabio Beltramini