Self-host scripts that are static and that you can review, such as libraries and fonts, because you control the bytes and the update moment. Load from a CDN only with an exact version and an integrity hash. Treat vendor scripts that must change remotely as a separate, higher risk group.
What changes when you self-host
The OWASP Third Party JavaScript Management cheat sheet lists mirroring vendor scripts in house as a way to prevent unauthorized alterations and to reduce the data sent to third parties. Two things follow.
First, the file only changes when you change it. A compromised CDN account or an expired domain cannot push new code to your visitors.
Second, you take on the update job. A copy you never refresh becomes an old, vulnerable library. Self-hosting trades supply chain surprise for maintenance debt, so it needs an owner.
What changes when you use a CDN
A CDN gives shared caching, global edge delivery and nothing to maintain. The risk is that the URL decides what runs. If the URL names a floating version, the content can change under you. If the URL names an exact version and carries an integrity hash, the browser refuses a changed file.
A decision table
| Script type | Suggested approach | Why |
|---|---|---|
| UI framework or utility library | Bundle it or self-host an exact version | Static, reviewable, scanned with your other dependencies |
| Web fonts and icon sets | Self-host | Static, and avoids sending visitor data to a third party |
| Polyfills | Self-host a reviewed build | Avoid a hosted service that can change behavior |
| Library from a public CDN | Exact version plus integrity hash | Cheap protection with a loud failure |
| Analytics and ad tags | Vendor hosted, tightly scoped | They change by design, so add CSP and monitoring |
| Payment or identity widgets | Vendor hosted, ideally in an iframe | Often required by the provider |
Steps to move a script in house
- Download the exact version you run today and record the source URL and date.
- Compare it with the vendor's published file or package so you know it is genuine.
- Add it to your repository or build, so it is covered by code review.
- Add the package to your dependency scanning so advisories reach you.
- Remove the old script tag and the CDN domain from your CSP.
- Set a recurring review, for example monthly, to bump the version.
Questions that settle edge cases
- Does the vendor require its own hosted URL for support or licensing? If yes, you cannot self-host.
- Does the script need frequent server side updates to work? If yes, a frozen copy will rot.
- Would a compromised version be able to read form fields or session data on this page? If yes, lean toward self-hosting or an iframe.
Related reading
The CDN supply chain risks post covers how things go wrong, and polyfill.io domain change lessons shows a hosted script changing under its users.
Safeguard scans dependencies and generates SBOMs, so a library you moved into your build gets the same advisory checks as the rest. A free scan is at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a bundled library shows up as an inventory entry you can track.
Quick check
Is self-hosting always safer than a CDN?
No. It removes remote tampering, but an outdated copy keeps known flaws. You need a refresh routine.
Can I get CDN benefits and still be safe?
Yes, with an exact version in the URL and an integrity attribute, so the browser rejects any changed file.
Sources
- OWASP, Third Party JavaScript Management Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Third_Party_Javascript_Management_Cheat_Sheet.html
- MDN, Subresource Integrity: https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity
Last reviewed: 19 October 2026.