QNimate

  • CoursesVideos
  • WP PremiumPlugins
  • DemosLab
  • Home
  • QIdea
  • QTrack
Home Carbon Ads Introduction to Subresource Integrity

Introduction to Subresource Integrity

subresource-integrity

Web technologies like TLS, HSTS and pinned public keys make sure that webpage resources are downloaded from the correct host. But these methods fail to verify if the downloaded resource is manipulated or not. For example, a attacker having access to the resource server can manipulate the resource(make it vulnerable to the app) and this kinds of attacks cannot be protected by using TLS or other similar technologies. Below image shows exactly how this attack is done.
Screen Shot 2014-08-31 at 4.51.11 pm
Till now administrators prevented this kinds of attacks by automatic checks for file and directory changes. If there is a change(attack) then admin used to restore the server to prevent the attacks. But there was no browser side method for stopping this attacks.

But now subresource integrity can protect from these kinds of attacks. Its a way of matching resources hash values with the hash value provided in the webpage. Ofcourse a attacker who can manipulate the resource can also manipulate the hash value in webpage therefore subresource integrity should only be used when the webpage host is different then the resources host i.e., while downloading third party resources like jQuery, Google maps scripts etc.

Subresource Integrity in Nutshell

Subresource integrity is achieved by attaching integrity attribute to HTML elements which downloads external resources(link, img, script, track, iframe, video, audio, a etc). This attribute to a value which is combination of resource hash value, hashing algorithm and MIME type of the file.

<script src="https://code.jquery.com/jquery-1.10.2.min.js"
       integrity="ni:///sha-256;C6CB9UYIS9UJeqinPHWTHVqh_E1uhG5Twh-Y5qFQmYg?ct=application/javascript">

“ni” in the integrity attribute stands for “named information”.
Here browser first downloads the script file and then matches the MIME type in HTTP header and hash of the returned code. If both are matched then the javascript code is executed otherwise ignored. If the file is a non-browser executable file(ex: .exe) then browser downloads it and if hash doesn’t match then it deletes the file.

Generating Hash of a file

Hash of a file(text or binary) can be generated using OpenSSL utility.

echo -n "file_content" | openssl dgst -sha256 -binary | openssl enc -base64 | sed -e 's/+/-/g' -e 's/\//_/g'

Make sure that the final hash is base64 encoded and choose sha256 or sha512 as hashing algorithm because all browsers support these two algorithms.

Fallback support

If the hash value of the resource is not matched then we might want the browser to download the resource from somewhere else. In that case we can provide the noncanonical-src attribute to provide the original resource location and if verification fails then resource attached to src(or main resource attribute) attribute is downloaded.

<script src="https://code.jquery.com/jquery-1.10.2.min.js" noncanonical-src="http://my-server.net/jquery.js"
       integrity="ni:///sha-256;C6CB9UYIS9UJeqinPHWTHVqh_E1uhG5Twh-Y5qFQmYg?ct=application/javascript">

This is mainly done for performance issue(HTTP is faster then HTTPS) and also for caching issues(some resource server forget to return caching headers). The non-canonical attribute usually points a resource location which is faster(HTTP) and also returns proper caching headers. If this location is hacked then browser fallbacks to an another location specified.

Integrity checks for <a> tag

Integrity(hash validation) checks can only be done on the anchor elements if there is a download attribute on the anchor element. So browsers completely downloads the resource and verifies its hash, if not matched then deletes the downloaded file.

If download attribute is not specified but integrity attribute is specified then user will not open the link. Its the only type of download support on the anchor elements.

Integrity check for resources fetched using JavaScript

Web workers, AJAX, HTMLElement objects, etc fetch external resources. We can also check their integrity.

For web workers we can pass the integrity attribute value to the constructor(new Worker) second parameter.

While creating HTML elements using JavaScript we can set the integrity attribute using setAttribute function.

XMLHttpRequest objects exposes a attribute called as integrity to which we can assign the ni string.


Conclusion
Subresource integrity is only supported by the latest browsers. Its will under heavy development. But you can start using it write away as non-supporting browsers will cause no harm. Thanks for reading.

Aug 31, 2014Narayan Prusty
Prioritising Downloading Of Webpage Resources SEO For E-Commerce Websites
Comments: 2
  1. Jolanta
    6 years ago

    Hi there,Thanks for publishing your pgiuln.Just sharing a modified version that I made to avoid using recursive functions.The comparison method seems a bit lengthy but I think it’s faster than doing regular expressions continuously.(function($) {if ($) {var escape_re = /[#;&,.+*~':”!^$=>|/]/,escapeCharacters = { #': 1, ;': 1, &': 1, ,': 1, .': 1, +': 1, *': 1, ~': 1, ‘: 1, :': 1, : 1, !': 1, ^': 1, $': 1, [‘: 1,’] : 1, ( : 1, )': 1, =': 1, >': 1, |': 1, /': 1, \': 1};$.escape = function(s){var ret = , offset;if (s && ((offset = s.search(escape_re)) !== -1)) { // look for an occurence of a special characterret = s.substr(0, offset) + \’ + s[offset];for(var i=offset + 1, len=s.length, ch; i < len; i++){ // assume that another special character may occur so we just loop through the rest of the stringch = s[i];ret += (escapeCharacters[ch]? ‘\': ”) + ch;}}return ret;};}})(window.jQuery);Cheers,Kayhadrin

    ReplyCancel
  2. qgustavor
    7 years ago

    I’m quite curious about a idea I have: does browsers really have to block HTTP requests from HTTPS pages when SRI is used? HTTPS means security and privacy, but as SRI gives the first one the second one can be applied just with a warning sign.

    In this case the message showed when the user clicks on the warning needs to be changed: “Your connection is secure, but isn’t private: an attacker can’t change what you see but can see some parts of what you’re browsing”.

    Of course that’s not optimal: “every website needs HTTPS, yadda yadda…”, but for cases like loading public available files, thus privacy isn’t needed, why not making this extra security layer optional? It’s already optional ( with warnings ) for media files, which in my opinion require more privacy than libraries.

    I don’t know where to suggest it, so I’m posting here. If someone reads help to improve this idea.

    ReplyCancel

Leave a Reply to Jolanta Cancel reply

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Narayan Prusty

I am a software engineer specialising in Blockchain, DevOps and Go/JavaScript. This is my personal blog where I write about things that I learn and feel interesting to share.

Image7 years ago 2 Comments Web Security
Share this
0
GooglePlus
0
Facebook
0
Twitter
0
Linkedin
  • Subresource Integrity in Nutshell
  • Generating Hash of a file
  • Fallback support
  • Integrity checks for <a> tag
  • Integrity check for resources fetched using JavaScript
Related Articles
  • Preventing CSRF Attacks In WordPress Using Nonces
  • How Does HTTP Authentication Work?
  • Digital Signature using Web Cryptography API
  • Hashing using Web Cryptography API
  • Website Hacking Methods and their Prevention
Our Sponsor
My Books

2014 - 2015 © QNimate
All tutorials MIT license