What’s in Your Website? Lurking Risk from Third-party Resources
Address Risk from Third-party Resources with Subresource Integrity (SRI)
In most real-life web apps there’s a need to include third-party resources. Whether it is for advertisements, A/B testing, analytics or other purposes, third-party resources provide important functional or business value.
When organizations are asked how they’re addressing the potential security risks, the people responsible for securing web apps usually reply that they have third-party scripts on their websites because it is a necessity imposed by business, and that they only work with third-parties that have a good reputation and can be trusted.
What Does Trust in Security Look Like?
This concept of trust in security is problematic, and we’ll explore the challenges in this post. It’s important to consider what happens if the provider of the third-party resource you’re working with gets compromised. In fact, it doesn’t even need to be compromised, it can simply have vulnerable code due to lack of developer knowledge or testing. This can leave your website exposed.
Most of these resources are scripts that are included in the websites and have total access to the Document Object Model (DOM). That means access to session cookies, inserted credentials, personal data, appearance, and practically everything of importance on your website.
Achieving Security with Subresource Integrity
The secure approach for using these scripts is to validate them before inclusion on the pages. To achieve that, the W3C recommends the Subresource Integrity (SRI) feature. It allows the browser to only execute scripts that were validated and authorized by you, and it is supported by most browsers:
How to Implement Subresource Integrity
To use SRI, the developer of the web app needs to provide the hashes of the scripts that are allowed to run. Then the browser validates downloaded scripts by matching these hashes. Here is an example:
<script src="script.js" integrity="sha384 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"></script>
Besides the script tag, web developers can also implement it with the link tag for stylesheet control:
<link rel="stylesheet" type="text/css" href="styles.css" integrity="sha384 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC">
Does Subresource Integrity Work?
We tested the different behaviors of Chrome, Firefox, IE, Edge, and Safari with the simple example shown below. We simulated malicious code by invoking a pop-up window and changing the text color to red. When the browser supports SRI, it blocks the pop-up window and keeps the default text color. However, when SRI is not supported, the pop-up displays and the text color changes to red.
Chrome 68:
Firefox 61:
Internet Explorer 11:
Edge 41:
Safari 11.1:
In these examples, the hash purposefully doesn’t match the actual files. The following screenshots are from Chrome, and show the behavior of the browser when these files are loaded with SRI:
The stylesheet defines the text with the red color, and the script pops an alert box, but they were blocked because of the invalid hash. The next screenshots show the result when not using SRI, with the same script and stylesheet. Notice that the debug console is completely empty.
Hash Generation
As you can see, the hash has a prefix identifying the hashing algorithm (sha256, sha384, and sha512), and the hash value itself is encoded with base64. Here are several ways of generating the hashes:
- using the online SRI Hash Generator at https://srihash.org/
- cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A
- shasum -b -a 384 FILENAME.js | xxd -r -p | base64
Secure Your Site with a Content Security Policy
You can use the Content Security Policy (CSP) to block every script or stylesheet that doesn’t have a hash associated in the page HTML code. This way, the pages guarantee that all the external scripts and stylesheets loaded by it are known and haven’t been changed. Here is the policy syntax:
Content-Security-Policy: require-sri-for script style;
To close the loop, add a report-uri directive, so that the website support staff can receive alerts whenever a script/stylesheet is blocked:
Content-Security-Policy: require-sri-for script style; report-uri: /csp-external-content-violation/
Current Status for the Content Security Policy: Browsers
The problem is that in current browser versions, for this policy to work, the users must tweak their browsers and activate the experimental features flag. Which, of course, is quite unlikely to happen.
If you want to activate this flag, try the following:
- [Chrome] URL chrome://flags/#enable-experimental-web-platform-features and change it to “Enabled”
- [Firefox] URL about:config ; and then search for the preference security.csp.experimentalEnabled and toggle the setting to “true”
The following video demonstrates the power of the require-sri-for policy. Notice the difference when the experimental features flag is activated. Keep in mind that the index.html file does not have SRI configured, and the index-integrity.html file does.
Current status for the Content Security Policy: Websites
Unfortunately, only 11 of the 500 most popular domains (from https://moz.com/top500) are using SRI in their main page, and none of these pages has the “require-sri-for” directive in their CSP, suggesting that this feature is still not widely used.
Call for Action
We call all browser vendors to actively support this policy.
Until then, try to implement the following:
- Make sure that every third-party resource is associated with a hash
- Create and periodically run a script to alert you in case the third-party resources have changed
Here is a simple bash script that saves the current versions of resources in use and can compare their current version with the previously saved one.
#!/bin/bash ## Third-party script change checker (tpscriptcc) ## Author: Joao Morais - 15-Jul-2018 ### Third-party scripts definition script_URL=( "http://third.party.site.com/script.js" "http:// third.party.site.com /script2.js" ) script_localname=( "script1" "script2" ) ### Options # --save-scripts - you need to use this option the first time you run the script. It saves the resources locally to compare in the future. ### Usage # tpscriptcc --save-scripts # tpscriptcc ### Code n=$((${#script_URL[@]}-1)) if [ $# -eq 0 ]; then for i in `seq 0 $n`; do wget -q "${script_URL[$i]}" -O "temp_file" r=$(diff temp_file "${script_localname[$i]}") if [ -n "$r" ]; then echo "${script_localname[$i]} was changed!" fi done else if [ $1 = "--save-scripts" ]; then for i in `seq 0 $n`; do wget -q "${script_URL[$i]}" -O "${script_localname[$i]}" done else echo "Usage: tpscriptcc [--save-scripts]" fi fi
Use this previous script as you like, and change it to send an email or an event to your monitoring system instead of displaying an alert message on the terminal.
We talked to Troy Hunt, a web security expert and founder of haveibeenpwned.com, well known for his public education outreach on security topics, about Subresource Integrity to get his take.
“SRI is an easy win you can implement for free and it solves a serious problem we’ve seen exploited many times this year alone. It’s also supported in all major browsers and gives you the best of both worlds: leveraging external services whilst also insuring against them changing in a malicious fashion. Especially when combined with a content security policy, SRI is now a must have.”
We hope you join us, and Troy Hunt, in embracing SRI and CSP. Use the script above, and encourage the web browsers to actively support this improvement.
Secure Your Third-party Resources with Subresource Integrity
Third-party resources are extremely prevalent, and a big risk. The good news is that it’s possible to minimize this risk with SRI, and most browsers are supporting SRI by default in their latest versions.
Managing resource integrity hashes can be time-consuming, but it’s time well spent because it results in much better control over your website. You may also want to consider using iframes to isolate these resources from your sites’ DOM. Otherwise, you’ll always have an extra vector for compromise – third-party resources.
References
https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
Latest posts by João Morais (see all)
- What’s in Your Website? Lurking Risk from Third-party Resources – October 9, 2018
- How Secure Are the Browser Extensions You Create? – October 3, 2018
*** This is a Security Bloggers Network syndicated blog from Blog – Checkmarx authored by João Morais. Read the original post at: https://www.checkmarx.com/2018/10/09/risk-third-party-resources/