Modern web applications rely heavily on third-party content delivery networks (CDNs) to serve JavaScript libraries, CSS frameworks, and other resources. While CDNs offer performance benefits and reduce server load, they also introduce potential security vulnerabilities. When your site loads external assets, you're essentially trusting that those files haven't been compromised or altered. That's where Subresource Integrity (SRI) becomes essential.
Understanding the Risk
Every time your website references an external script or stylesheet, you're placing trust in that third-party provider. If a CDN gets compromised or an attacker gains control of those files, malicious code could be injected and served to your visitors without your knowledge. This type of supply chain attack has affected major websites and can lead to data theft, unauthorized access, or damage to your reputation.
For businesses running websites, particularly those handling customer data or transactions, these risks aren't theoretical. Your domain registration and hosting infrastructure might be secure, but a compromised CDN resource can bypass all those protections. How Subresource Integrity Works
SRI allows browsers to verify that files fetched from external sources haven't been tampered with. It works by comparing a cryptographic hash of the downloaded file against a hash you specify in your HTML. If the hashes don't match, the browser refuses to execute the resource.
Here's what a basic SRI implementation looks like:
<script src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxQ..."
crossorigin="anonymous"></script>
The integrity attribute contains the hash, while crossorigin is necessary for the browser to perform the integrity check on resources from different origins.
Implementing SRI: Best Practices
Choose Strong Hash Algorithms
SRI supports SHA-256, SHA-384, and SHA-512. We recommend using SHA-384 or SHA-512 for production environments. These algorithms provide robust protection against collision attacks while maintaining reasonable performance.
Pin Specific Versions
Always reference specific versions of third-party libraries rather than using "latest" or unversioned URLs. This practice serves two purposes: it ensures your SRI hashes remain valid, and it prevents unexpected breaking changes from automatic updates.
<!-- Good: Specific version -->
integrity="sha384-..."></script>
<!-- Avoid: Generic or latest version -->
<script src="https://cdn.example.com/library/latest/library.min.js"></script>
Set the Crossorigin Attribute Correctly
The crossorigin attribute tells the browser how to handle cross-origin requests. For public CDN resources, use crossorigin="anonymous". This allows the browser to fetch the resource without sending credentials while still performing integrity checks.
Generate Hashes Accurately
Generating SRI hashes is straightforward. You can use command-line tools or online generators:
openssl dgst -sha384 -binary library.js | openssl base64 -A
For production workflows, consider using automated tools that integrate with your build process. This reduces human error and ensures every external resource includes proper integrity verification.
Automating SRI in CI/CD Pipelines
Manual hash generation becomes impractical as your project grows. Integrating SRI into your continuous integration and deployment pipeline ensures consistency and reduces maintenance overhead.
Build-Time Hash Generation
Tools like webpack, Rollup, and Parcel offer plugins that automatically generate SRI hashes during the build process. For example, the webpack-subresource-integrity plugin calculates hashes for all your bundled assets and injects them into your HTML templates.
// webpack.config.js example
const SriPlugin = require('webpack-subresource-integrity');
crossOriginLoading: 'anonymous',
hashFuncNames: ['sha384'],
Verification in Testing Environments
Your CI pipeline should include steps to verify that all external resources have valid SRI attributes. Automated tests can scan your built HTML files and flag any external scripts or stylesheets missing integrity checks. This prevents deployments with unprotected resources from reaching production.
Version Control for Hashes
Store SRI hashes in configuration files that live alongside your code. This approach makes it easier to track changes, review updates, and roll back if needed. When you update a library version, your CI system should automatically recalculate the hash and update the configuration.
Planning Safe Fallbacks
While SRI provides strong protection, you need to consider what happens when integrity checks fail. Failed checks could result from legitimate library updates, CDN issues, or actual security incidents.
Local Fallback Resources
Maintain local copies of critical resources that your site can fall back to if CDN-hosted versions fail integrity checks. This approach ensures your site remains functional even if a CDN serves compromised or incorrect files:
<script src="https://cdn.example.com/library.js"
crossorigin="anonymous"></script>
if (typeof Library === 'undefined') {
document.write('<script src="/local/library.js"><\/script>');
Your hosting environment should include these fallback copies with proper cache headers to minimize performance impact. Monitoring and Alerts
Implement monitoring to detect when SRI checks fail in production. Browser console errors won't help you unless you're actively collecting them. Use error tracking services to capture integrity failures and investigate them promptly. Frequent failures might indicate CDN issues, while isolated incidents could signal attempted attacks.
Update Procedures
Establish clear procedures for updating external dependencies. When upgrading a library:
- Test the new version in a development environment
- Update your HTML templates or configuration files
- Deploy through your standard CI/CD pipeline
- Monitor for any integrity failures post-deployment
This systematic approach prevents broken sites due to hash mismatches while maintaining security.
Common Pitfalls to Avoid
Dynamic Content and SRI
SRI only works with static files. If a CDN dynamically generates or modifies content, SRI checks will always fail because the hash won't match. Ensure any external resources you protect with SRI are truly static and versioned.
Multiple Hash Algorithms
You can specify multiple hash algorithms for a single resource, and the browser will verify using the strongest one it supports:
<script src="https://cdn.example.com/library.js"
integrity="sha256-... sha384-..."
crossorigin="anonymous"></script>
However, this adds complexity without significant benefit in most cases. Pick one strong algorithm and use it consistently.
Missing Crossorigin Attributes
Forgetting the crossorigin attribute is a common mistake that prevents SRI from working. Without it, browsers won't perform integrity checks on cross-origin resources. Always include this attribute when implementing SRI.
Beyond SRI: Layered Security
SRI is one component of a comprehensive security strategy. Combine it with other protective measures:
- Content Security Policy (CSP): Restrict which domains can serve resources to your site
- HTTPS: Ensure all connections use SSL certificates to prevent man-in-the-middle attacks
- Regular Audits: Periodically review all third-party dependencies and remove unused ones
When you're running a business online, security involves multiple layers of protection. Your infrastructure, from domain configuration to server setup, should work together to protect your users.
Making SRI Part of Your Development Culture
The most effective security measures are those that become routine. Make SRI implementation part of your standard development checklist:
- Review external dependencies during code reviews
- Require SRI attributes for any new third-party resources
- Educate team members about supply chain security risks
- Keep documentation updated with your SRI implementation patterns
Conclusion
Subresource Integrity provides meaningful protection against supply chain attacks through compromised CDN resources. While implementing SRI requires initial setup and ongoing maintenance, the security benefits justify the effort. By generating proper cryptographic hashes, pinning specific versions, automating verification in your CI/CD pipeline, and planning appropriate fallbacks, you create a more resilient web application.
Third-party resources will remain an essential part of modern web development, but that doesn't mean you have to accept the security risks they introduce. SRI gives you verification without sacrificing the performance benefits of CDNs. Start implementing it today, beginning with your most critical external dependencies, and expand coverage as you refine your processes.