Enabling Subresource Integrity for Rainforest

Russell Smith, Sunday February 28, 2016

Subresource integrity is pretty new, it lets you as the owner of a website, specify a cryptographic digest (aka: hash) of your pages subresources like Javascript, CSS, etc.

Whats the point? To make sure the code you request is the code you’re running.

We’ve started by just implementing it on our own resources by adding a few lines to our deployment script, plus a couple of extra attributes to our script tags.

Rainforest’s front end is in its own repo, a project call Regenwald (German for Rainforest) contains all our React, Backbone and other Javascript. We use CircleCI to build and deploy everything to AWS S3.

As we’re not yet completely static apart from the API, we set an environment variable on our Rails app, letting it know the right SRI hash, plus the build location for the latest code:

heroku config:set REGENWALD_SHA=$CIRCLE_SHA1 REGENWALD_SRI="sha384-$(cat public/javascripts/app.js | openssl dgst -sha384 -binary | openssl enc -base64 -A)" -a our-staging-app

The env var is then used to generate some HTML:

<script src="//static.rainforestqa.com/7895d4b1720e696e6a80fb19715063914fdcf987/javascripts/app.js" integrity="sha384-y4NT9AZschAM7lHPKiCpsCLBC6+KfjJ61z1QIgmRmKb35cgwy+cLM9W8tqCxoVu7" crossorigin="anonymous"></script>

Note, crossorigin is set to anonymous, meaing that no cookies or other auth is shared with the subresource.

How to implement SRI in three steps

$(cat public/javascripts/app.js | openssl dgst -sha384 -binary | openssl enc -base64 -A)
  1. cat the file to be hashed to openssl: cat path/to/file.js
  2. make the digest (can be sha 256 / 384 / 512, we use 384 as it’s a sane length): openssl dgst -sha384 -binary
  3. base64 encode the binary sha: openssl enc -base64 -A

Further reading:

Interesting? We're looking for hungry hackers who love testing and building tools for other developers. Click here to get in touch.