Like many sites, GitHub uses a content delivery network (CDN) to serve static assets such as JavaScript, CSS, and images to our users. The CDN makes web browsing faster by delivering assets from data centers that are geographically close to the end user and by using hardware and software that is optimized for quickly serving static assets.
For companies that go to great lengths to protect their users from Cross-Site Scripting (XSS) vulnerabilities, relying on a CDN to serve JavaScript means relinquishing control over the content of JavaScript and fully trusting the CDN. While it is not often discussed, and while many CDNs have a great security track record, the compromise of a major CDN could be devastating to the security of the hundreds of thousands of sites that depend on it. If our CDN were to be compromised, it could be used to serve malicious JavaScript to all our users, rendering our many XSS mitigations and transport security useless. Content Security Policy is invaluable for protecting against traditional XSS attacks, but it provides no defense against an attacker who can control assets served from whitelisted sources.
A new browser technology called Subresource Integrity gives websites more control over the assets their pages fetch from CDNs or other third parties. The website author includes an integrity
attribute on JavaScript and CSS tags, specifying the cryptographic digest of the resource being loaded from the third party. When the browser fetches the resource, it computes the file’s digest and compares it with the value from the integrity
attribute. If the values match, the resource is loaded. Otherwise, the browser refuses to load the resource.
Ruby on Rails apps can use sprockets-rails
support for computing and adding the integrity
attribute:
javascript_include_tag :application, integrity: true
# => "/assets/application.js"
For sites using Subresource Integrity, a compromised CDN is eliminated as a XSS vector. While for many sites this might not seem like the most plausible attack, third party analytics scripts have been hijacked in the past to inject malicious JavaScript. Widespread adoption of Subresource Integrity could have largely prevented the Great Cannon attack earlier this year.
GitHub has always been vigilant about XSS and other vulnerabilities, finding and fixing them internally as well as through our Bug Bounty Program. We were also early adopters of another XSS mitigation, Content Security Policy, and are always working to harden that policy. Now, Subresource Integrity adds another layer of mitigation, further raising the bar for attackers.
New browser security features like Subresource Integrity are making the web a safer place. They don’t do much good if websites don’t implement them though. We’re playing our role, and encourage you to consider doing the same.
Browser support at the time of this article’s publishing:
- Google Chrome added support in version 45{: data-proofer-ignore=”true”}
- Mozilla Firefox plans to add support in version 43 (Nightly. Developer Edition as of next Monday)
- Microsoft Edge support is “under consideration”. Vote for the feature here.
Written by
Related posts
CodeQL zero to hero part 4: Gradio framework case study
Learn how I discovered 11 new vulnerabilities by writing CodeQL models for Gradio framework and how you can do it, too.
Attacking browser extensions
Learn about browser extension security and secure your extensions with the help of CodeQL.
Cybersecurity spotlight on bug bounty researcher @adrianoapj
As we wrap up Cybersecurity Awareness Month, the GitHub Bug Bounty team is excited to feature another spotlight on a talented security researcher who participates in the GitHub Security Bug Bounty Program—@adrianoapj!