The Problem: Do You Truly Trust Your CDN?
Most of us are in the habit of embedding libraries like jQuery, Bootstrap, or FontAwesome via major CDNs such as Cloudflare, Google, or cdnjs. The benefits are clear: faster loading speeds, reduced server bandwidth, and leveraging the user’s browser cache.
However, after conducting security audits for numerous projects, I’ve noticed a critical vulnerability. Most developers simply copy-paste the script link while forgetting to verify the file’s content.
Reality has proven this isn’t just a paranoid concern. Look at the recent Polyfill.io attack, where over 100,000 websites unknowingly loaded malware because the CDN domain changed ownership. When a CDN server is compromised, hackers can replace a legitimate jquery.min.js file with a “modded” version containing malware to steal credit card info or cookies. The browser still executes this code because it fully trusts the CDN’s domain. This is a classic and extremely dangerous Supply Chain Attack.
To thwart this threat, Subresource Integrity (SRI) serves as the final layer of armor for your website.
How Subresource Integrity (SRI) Works
SRI allows the browser to verify whether a downloaded file has been tampered with by using a cryptographic hash.
When you embed a file with a hash, the browser follows a 4-step process:
- Download the file from the CDN into temporary memory.
- Calculate the file’s hash using the specified algorithm (usually SHA-384).
- Compare the calculated hash with the hash declared in the
integrityattribute. - If they match, the browser executes the file. If there is even a single character difference, the browser blocks the file and logs a bright red error in the console.
Thanks to this mechanism, even if the CDN server is hacked, the malware has no chance of running on your users’ machines.
How to Implement SRI in Real-World Projects
1. Generating Hashes Manually
For small projects using only a few libraries, you can quickly generate a hash via the terminal. Suppose you need to create a SHA-384 hash for an app.js file.
On Linux or macOS, use the following command:
cat app.js | openssl dgst -sha384 -binary | openssl base64 -A
The result will be a long Base64 string. If you prefer not to use the command line, use srihash.org. Simply paste the CDN link, and the tool will generate the complete HTML snippet for you.
2. Configuring HTML with the integrity Attribute
Once you have the hash, add it to the <script> or <link> tag. Don’t forget the crossorigin="anonymous" attribute. Without it, the browser will skip the SRI check for cross-domain security reasons.
Example of a proper Bootstrap embed:
<!-- Embed CSS -->
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"
crossorigin="anonymous">
<!-- Embed JS -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
crossorigin="anonymous"></script>
3. Automating with Webpack
Manually generating hashes for dozens of files every time you update is impossible. If you use Webpack, let the webpack-subresource-integrity plugin handle it.
Install the plugin:
npm install webpack-subresource-integrity --save-dev
Configuration in webpack.config.js:
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
module.exports = {
output: {
crossOriginLoading: "anonymous",
},
plugins: [
new SubresourceIntegrityPlugin({
hashFuncNames: ["sha384"],
enabled: process.env.NODE_ENV === "production",
}),
],
};
This plugin will automatically calculate and insert the hash into your HTML files every time you run a production build.
4. Fallback Strategy (Redundancy for CDN Failures)
The downside of SRI is that if the hash doesn’t match, the browser blocks the file entirely. Your website’s layout might break if the CSS fails to load.
The best solution is to always have a local copy ready. Here is a small JavaScript trick to automatically reload the file from your own server if the CDN fails:
<script src="https://code.jquery.com/jquery-3.7.0.min.js"
integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
crossorigin="anonymous"></script>
<script>
if (window.jQuery === undefined) {
document.write('<script src="/js/vendor/jquery-3.7.0.min.js"><\/script>');
}
</script>
Critical Considerations
- CORS is mandatory: The CDN server must support CORS. Most major providers like Cloudflare or JSDelivr have this enabled by default.
- Be careful when upgrading: When you change a library version (e.g., from
v3.6.0tov3.7.0), the hash will definitely change. If you forget to update theintegrityattribute, the browser will block the file immediately. - Prioritize SHA-384: This is currently the gold standard—high security without burdening browser performance.
Conclusion
Implementing SRI takes very little effort, but the security value it provides is immense. Don’t let a small oversight put thousands of your users at risk. Check the script tags on your website today!

