Browse enough code that loads JavaScript or CSS from an external CDN, and sooner or later you run into something like this.
<script
src="https://cdn.example.com/library.min.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>
I vaguely knew that the integrity attribute had something to do with security. Once I actually started thinking about it, though, the questions kept coming. If you serve over HTTPS, isn't that enough? Do you still need it when you install via npm?
I also wondered how it differs from CSP, and what it means for apps built with Next.js or Vite. And, most puzzling of all, for something that sounds so important, I almost never see it in everyday web development. What gives?
So I went through the Subresource Integrity (hereafter SRI) specification, the attacks it can actually prevent, past incidents, and how it relates to modern build environments. To get it out of the way: SRI is not an all-purpose security feature. That said, when you load fixed-version JavaScript or CSS from an external CDN, it is still a relatively cheap and highly effective measure.
The trouble is third-party scripts whose contents change all the time. Google Tag Manager, ads, analytics tools, A/B testing tools: SRI is hard to apply to any of them. Ironically, the riskier the script, the harder it is to put SRI on it.
As a mechanism, SRI works a lot like an old-fashioned tally stick. The HTML holds one half, the hash, and the browser checks whether the file that arrives fits as the other half. So rather than declaring "thou shalt always use SRI," I'll work through which setups actually make this tally worth carrying.
Pinning Content with a Hash
To begin with, SRI is a mechanism in which the browser checks the content of a fetched JavaScript or CSS file against the hash value written in the HTML. Suppose there is a script tag like this.
<script
src="https://cdn.example.com/library.min.js"
integrity="sha384-BASE64_HASH"
crossorigin="anonymous"
></script>
The browser first fetches the file specified in src and computes a hash from its content. It then compares that with the value in the integrity attribute and executes the JavaScript only if they match. If they don't, the load itself fails.
The key point is that on a mismatch, the browser doesn't go easy by issuing a warning and quietly running the thing anyway. The resource is treated as a network error: JavaScript is not executed, and CSS is not applied. In other words, SRI is a browser-side check of "is this file really the content we approved in advance?" The W3C SRI specification likewise defines it as a mechanism by which the user agent verifies that a fetched resource has not been unexpectedly manipulated.
Let's look at actual usage too. Loading Bootstrap and the like from an external CDN looks like this.
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
integrity="sha384-..."
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>
The main supported hash algorithms are SHA-256, SHA-384, and SHA-512. In practice, SHA-384 is the common choice. To generate a hash from a local file, you can compute it like this, for example.
openssl dgst -sha384 -binary library.min.js | openssl base64 -A
Prepend sha384- to the output and put it in the integrity attribute.
integrity="sha384-generated-Base64-string"
Why crossorigin Is Needed
When using SRI on a resource from another origin, you normally specifycrossorigin="anonymous" as well.
<script
src="https://cdn.example.com/library.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>
The reason is that for cross-origin requests with SRI, the browser fetches the response using CORS. Naturally, the CDN serving the file also has to return a CORS response header such as the following.
Access-Control-Allow-Origin: *
Why go to all this trouble? Because if hash checking were freely allowed on cross-origin opaque responses, an attacker could use whether the hash matches as a clue to infer the content of another origin. So if the CDN doesn't support CORS, an SRI resource may fail to load even with the correct hash written in.
HTTPS Guards a Different Place
This is where I got stuck first. HTTPS encrypts the communication channel and prevents eavesdropping and tampering in transit. So surely SRI is unnecessary?
As it turns out, what the two protect is subtly different. HTTPS mainly guarantees that the party you're talking to is the host matching the certificate. It also makes the content hard to snoop on or rewrite in transit. SRI, by contrast, verifies one thing and one thing only: that the fetched file matches the content the developer approved in advance.
Say the legitimate CDN itself is compromised and returns malicious JavaScript over a legitimate HTTPS connection. As far as HTTPS is concerned, nothing is wrong. The other party is the legitimate CDN, and the channel is properly encrypted. Only the content of the file that arrived has been swapped for something malicious.
If SRI is specified, the browser notices that the halves don't fit and can stop execution. In short, HTTPS is a mechanism for trusting the channel, and SRI is a mechanism for verifying what arrives through it. They aren't substitutes for each other; they complement each other.
When the URL Is Right but the Content Isn't
SRI is effective, basically, in situations where "the URL is correct, but what comes back from it has changed." The textbook case is a file on an external CDN being rewritten by an attacker. The hash no longer matches, so the browser stops execution. If a third-party service's server or account is hijacked and malicious JavaScript is served from the same URL, that too can be detected as long as the hash on the HTML side hasn't been updated.
Mind you, the adversary isn't always malicious. If a CDN misconfiguration or cache inconsistency returns a different file, SRI dutifully stops the load. Pinning the version in the URL doesn't make you safe, either. Even with a URL likehttps://cdn.example.com/library/1.2.3/library.min.js, there's a nonzero chance the origin later swaps out the file at that same URL.
SRI pins the actual content of the file rather than the URL, so it catches that as well. If a DNS attack or CDN cache poisoning steers you to a different server or different content, the file is still blocked as long as it differs from the prior hash. That said, if the HTML is rewritten at the same time, there's nothing SRI can do.
Organized by threat, it looks like this.
| Threat / incident | SRI effectiveness | Reason |
|---|---|---|
| Tampering with JavaScript on a CDN | High | If the content changes, the hash won't match |
| Compromise of an external content provider | High | Detectable even if malicious files are returned from the same URL |
| CDN serving the wrong file | High | Unexpected content is blocked regardless of the cause |
| Replacement of a fixed-version URL | High | Pins the content, not the URL |
| CDN cache poisoning | Conditional | Effective when only the served content changes |
| DNS hijacking | Conditional | Effective when the HTML stays safe and only the external resource is swapped |
| Man-in-the-middle attacks | Conditional | HTTPS is the first line of defense. Adds verification if the content changes |
| npm package compromise | Generally ineffective | Compromise occurs in the build process before it reaches the browser |
| Tampering with the HTML itself | Ineffective | Both src and integrity can be rewritten |
| XSS | Ineffective | A different problem from integrity verification of external files |
| CSRF | Ineffective | Not a mechanism for preventing request forgery |
When Both Halves Are Forged
To get a feel for where SRI's responsibility ends, it's quicker to look at what it can't prevent. First, it is utterly helpless against tampering with the HTML itself. The hash lives in the HTML, so an attacker who can rewrite the HTML simply swaps outsrc and integrity together.
<script
src="https://attacker.example/malware.js"
integrity="sha384-correct-hash-computed-by-the-attacker"
></script>
SRI treats the HTML as its root of trust. If the place holding your half of the tally falls, the attacker gets to carve both halves however they like.
Second, it can't stop an officially published malicious version. Suppose the maintainer of a dependency is compromised and a malicious version is published, bold as brass, to npm or a CDN. If a developer grabs that file without checking its content and updates the hash, SRI waves it through as if nothing happened. What SRI checks is "does this match the approved content," not "is this code safe."
By the same logic, in cases likeua-parser-js and event-stream, where malicious code was planted in the npm package itself, SRI is generally of no use. The malicious code is fetched from npm and folded into your own JavaScript as part of the build output. From the browser's point of view, it's a perfectly legitimate file of your own.
What this territory calls for is a different set of measures. Lockfiles, npm audit, Dependabot or Renovate, and package signing and provenance come first. Dependency review, protection of the CI/CD environment, and verification of build artifacts are just as indispensable.
Finally, XSS and CSRF are out of scope too. SRI is merely a feature for verifying the content of external resources. It doesn't directly prevent XSS, where scripts are injected via user input, or CSRF, where the victim is made to send forged requests. The main players in XSS defense are CSP, output escaping, Trusted Types, and the like.
How It Differs from Lockfiles and Content Hashes
package-lock.json and pnpm-lock.yaml also record integrity information for dependency packages. In npm's package-lock.json, for example, you'll find a value like this.
{
"integrity": "sha512-..."
}
It looks just like SRI, but the timing of verification is entirely different. Lockfile integrity checks, at the moment an npm package is installed, that the fetched tarball is what was expected. What it guards is the stretch from the npm registry to your development environment or CI.
Browser SRI, on the other hand, verifies at the moment a user fetches JavaScript or CSS in production. What it guards is the stretch from the CDN or web server to the user's browser. Similar hash format, different stage of the pipeline.
| Mechanism | When verified | Main purpose |
|---|---|---|
| lockfile integrity | At package install time | Integrity and reproducibility of package retrieval |
| SRI | When the browser fetches the resource | Verifying the content of served files |
So "we have a lockfile, so SRI is unnecessary" doesn't necessarily hold. That said, things change in a setup where you bundle libraries fetched via npm yourself and serve them from your own domain. There, the extra benefit of SRI is smaller than when reading directly from an external CDN.
A similar misconception surrounds filenames with a content hash. With Vite and Webpack, built files sometimes get names likeassets/index-a8f45c2d.js. At first glance this also looks like content verification, but its main purpose is cache control. When the content changes, index-a8f45c2d.js becomes index-b71d903a.js, which makes it easy to get browsers to fetch the new file.
The browser, however, never checks the hash portion of the filename against the actual content. If an attacker or a CDN misconfiguration causes different content to come back from the same URL, the filename alone won't notice. A content hash is merely a tool for cache invalidation and versioning. Verifying the content in the browser is SRI's job and SRI's alone.
A Division of Labor with CSP
The technology most often mentioned alongside SRI is Content Security Policy (CSP). CSP restricts which origins a page may load scripts, images, and so on from.
Content-Security-Policy: script-src 'self' https://cdn.example.com
This example allows scripts from your own origin and from cdn.example.com. But if cdn.example.com itself is compromised, the picture changes. Malicious code served from that same host will sail right through host-based CSP alone. That's where SRI comes in, checking that the content of a file fetched from an allowed host is what you expected.
In other words, CSP controls "where things can be loaded from," and SRI verifies "what the loaded content is." Because their roles differ, they work well together. For screens that demand high security, I'd want HTTPS, CSP, and SRI, plus a reduced set of external scripts, Trusted Types, and dependency monitoring.
While we're at it: CSP once had a directive calledrequire-sri-for.
Content-Security-Policy: require-sri-for script style
It was meant to make SRI mandatory for script and style. Due to standardization and browser implementation issues, however, it is now removed and deprecated. New implementations should steer clear of relying on it.
Not exactly as its replacement, but from 2025 onward, implementation of the newIntegrity-Policy header has been progressing.
Integrity-Policy: blocked-destinations=(script)
Integrity-Policy is a new mechanism for requiring integrity verification on target resources and for collecting violations through the Reporting API. Script support is progressing in Chrome 138 and Firefox 145 and later. SRI itself became a W3C Recommendation in 2016, yet work on extending related specifications continues even as of 2026. Rather than writing it off as an "old, finished technology," it's more accurate to see a mature core with enforcement and monitoring features being added around it.
Did It Help in Past Incidents?
So, did SRI actually help in real incidents?
In 2024, Polyfill.io started serving malicious JavaScript. An external JavaScript service was compromised and abused, so that malicious JavaScript could run in visitors' browsers even though the sites using it hadn't changed a single line of code. A textbook supply chain attack. If the file in question had fixed content and SRI had been set up beforehand, the unauthorized swap might have been caught.
Polyfill.io, however, was a dynamic service that changed what it returned depending on the User-Agent and the features requested. When the content varies per user even at the same URL, it's a poor match for SRI, which specifies a fixed hash in the first place. Strong against replacement of fixed files, hard to apply to services whose content changes dynamically. This one incident shows off both the strength and the limits of SRI in a single stroke.
In the Ticketmaster case, malicious code was inserted into the JavaScript of a third-party chat service used on the payment page, and customer data was leaked. If that JavaScript was a fixed file loaded from an external URL and the HTML side hadn't been tampered with, SRI might have prevented it. Then again, depending on how it was actually loaded and updated, SRI might not have been applicable at all. I can't go so far as to say "SRI would surely have prevented it."
British Airways had JavaScript that steals payment information injected into its website. This was a so-called Magecart breach. In this case, the site's own scripts or HTML may have been compromised, and then an attacker can rewrite the SRI along with them. It's hard to believe SRI alone could have stopped it.
ua-parser-js and event-stream are cases where malicious code was published in the npm packages themselves. The compromised code is pulled into the app at build time, so it falls outside the reach of browser SRI.
Lined up like this, it becomes clear that even among "supply chain attacks," some are within SRI's reach and some are not. SRI works against runtime file replacement on an external CDN. Compromise of npm, CI, or the build process is generally beyond it.
Where It Fits and Where It Doesn't
SRI pays off most obviously when loading fixed-version libraries from an external CDN. Think Bootstrap, jQuery, Prism.js, Highlight.js, Font Awesome, fixed UMD builds of React, that sort of thing. If both the URL and the content are fixed, all you have to do is update the hash when you upgrade. The payoff is large relative to the effort, so adding it as a rule is the sensible call.
Even static sites with no build environment can adopt it just by addingintegrity to external CDN tags. It's an especially good fit for GitHub Pages, static landing pages, CMS-managed pages, documentation sites, and corporate sites that rarely change.
In WordPress, too, you can add integrity and crossorigin using the hooks that output scripts and styles. If you're using fixed files from an external CDN, it's worth doing. If a theme or plugin updates URLs on its own, though, you'll need to keep an eye on whether the hashes still line up.
On pages that handle admin privileges or personal information, such as admin screens and payment screens, you should cut third-party JavaScript down as far as possible. If you still have to load external resources, the priority of SRI shoots up. On payment screens in particular, the compromise of a single third-party script can be enough to have every bit of entered data carted off.
Conversely, scripts like Google Tag Manager, ads, and analytics tools get their content updated frequently even at the same URL. Put SRI on them and the hash breaks on every update, stopping the script. Unless you plan to hire someone whose sole job is updating hashes around the clock, that won't fly, and I doubt anyone would apply. For this reason, SRI often can't be realistically operated with Google Analytics, ad tags, tag managers, A/B testing tools, and the like.
This is a rather structural problem. The riskiest third-party scripts are precisely the ones whose content changes constantly, which makes them the hardest to apply SRI to.
In this territory, you lean on measures other than SRI. Remove unnecessary tags, restrict who can add them, and limit destinations with CSP. Isolate with iframes or sandbox, and monitor changes to third-party scripts. Or simply don't load them on payment screens at all.
Dynamic widgets for chat, customer support, personalization, and A/B testing are in the same boat, since what gets served may vary per user or per configuration. In that case, a single hash value can't pin the content.
Webpack Module Federation is a bit of a headache too, becauseremoteEntry.js and the chunks that follow are loaded dynamically at runtime. Applying SRI is possible in itself, but the shopping list is long: pinning the version of remoteEntry, distributing hash values, setting integrity when inserting scripts dynamically, managing hashes for subsequent chunks, and keeping deployments consistent between host and remote. Compared with plain CDN loading, the operational difficulty is considerably higher.
Pitfalls with ES Modules and Compression
With ES Modules, can you get away with putting SRI only on the entry point? Unfortunately not. Suppose you have a module like this.
<script
type="module"
src="/assets/main.js"
integrity="sha384-..."
></script>
Even if main.js imports other modules, the entry point's SRI does not automatically propagate to all its dependencies.
import "./feature.js";
import("./lazy.js");
Only the initial fetch of main.js is verified. The child modules aren't looked after by that same hash. As a way to give dependent modules integrity information too, the integrity key in import maps has been standardized.
<script type="importmap">
{
"imports": {
"app": "/assets/main.js"
},
"integrity": {
"/assets/main.js": "sha384-...",
"/assets/feature.js": "sha384-...",
"/assets/lazy.js": "sha384-..."
}
}
</script>
Real build output, however, contains a great many chunks. If you want SRI on every chunk in Vite, Webpack, Next.js, and so on, a mechanism that generates hashes automatically at build time is all but essential. Try doing it by hand and the next release will be out before you've finished pasting.
Compression, on the other hand, is nothing to worry about. HTTP compression with gzip or Brotli is normally compatible with SRI. That's because the browser uses the content after undoing transfer compression. Whether the same JavaScript goes out as gzip or Brotli, you normally don't need to change the hash.
The trouble comes from processing that alters the JavaScript or CSS content itself along the way. Think automatic minification on the CDN, rewriting JavaScript, per-User-Agent code transformation, swapping files by region, content changes from A/B testing, and per-user optimization at the same URL. If the code the browser finally receives changes, the hash naturally won't match. Features that change how script tags or JavaScript are loaded, such as Cloudflare's Rocket Loader, can also cause compatibility problems.
So it's safer to hold files that use SRI to a few conditions. They should always return the same content for the same URL and never be transformed on the CDN side. Serve them as immutable files, with a version or content hash in the URL.
The Price of Availability
SRI won't execute a resource whose hash doesn't match. That's the correct behavior for security, but from an operations standpoint it's also a seed of outages.
Say a deployment goes out of sync: the new HTML carries the new hash, but old JavaScript is still sitting pretty at the CDN edge. The hash won't match, and the app may fail to start. The same happens the other way around, when old HTML references new JavaScript.
Quite a few setups call for extra care. Blue-Green Deployment, rolling deployments, deploying HTML and static assets separately, and long HTML cache lifetimes top the list. Slow CDN cache purges and large numbers of dynamic chunks belong there too. If you adopt SRI, you have to think not only about security but also about deployment atomicity and cache strategy.
There's also the option of falling back to a self-hosted copy when loading from the CDN fails.
<script>
function loadLocalLibrary() {
const script = document.createElement("script");
script.src = "/assets/library.min.js";
script.integrity = "sha384-LOCAL_HASH";
script.crossOrigin = "anonymous";
document.head.appendChild(script);
}
</script>
<script
src="https://cdn.example.com/library.min.js"
integrity="sha384-CDN_HASH"
crossorigin="anonymous"
onerror="loadLocalLibrary()"
></script>
More fallbacks, however, mean more headaches. It becomes hard to tell a CDN outage from an SRI mismatch, and the fallback destination also has to be allowed in CSP. You end up managing several hashes, failure analysis gets tangled, and the fallback copy may quietly go stale. It's practical for loading a handful of fixed libraries, but not realistic for the mountain of chunks in a large SPA.
What to Do with React, Vite, and Next.js
React itself has no feature for managing SRI. If you load React directly from a CDN UMD build, it's worth adding SRI as you would for any external CDN. If you install it via npm and bundle it with Vite or Webpack, on the other hand, SRI becomes the build tool's responsibility.
For Webpack,webpack-subresource-integrity is the go-to option. It can generate SRI including dynamic chunks. You do need to verify compatibility with your Webpack version and HTML generation plugin, though.
Vite itself can hardly be said to have general-purpose automatic SRI properly built in as a standard feature. Community plugins are the main route, with candidates including vite-plugin-manifest-sri, vite-plugin-sri-gen, and other SRI generation plugins.
Their coverage is all over the map, though. Some add integrity directly to the HTML, some add hashes to the manifest, some also handle modulepreload, and some go as far as dynamic chunks. When adopting one, check its maintenance status and exactly what it generates.
Next.js has experimental support for hash-based CSP using SRI for the App Router. Being experimental, it comes with limitations around build methods, routers, and static generation. More fundamentally, the value of adding SRI to all the regular chunks Next.js serves itself is not as clear-cut as for fixed libraries on an external CDN. If the HTML and assets live on the same deployment platform and inside the same trust boundary, an attacker who can rewrite the HTML can recarve both halves of the tally at once.
That doesn't make it pointless, though. It becomes meaningful in setups such as serving static assets from a separate CDN, inserting edge transformations, or coordinating with a strict CSP.
Decisions by Setup
Pulling everything so far together by setup gives the following table.
| Setup | Recommendation | Judgment |
|---|---|---|
| Load fixed-version JS/CSS from an external CDN | High | The representative use of SRI. Add it in principle |
Load latest from an external CDN | Low | Better to pin the version before even thinking about SRI |
| Load Bootstrap from a CDN in static HTML | High | Easy to adopt and the benefit is clear |
| Load fixed CDN libraries in WordPress | Medium to high | Effective if you can manage hash updates |
| Load fixed external scripts on a payment screen | High | Reducing external scripts comes first. Use SRI if needed |
| SPA built in-house with packages from npm | Low to medium | Smaller additional benefit than with external CDN use |
| Serve content-hashed files from your own CDN | Low to medium | Meaningful when trust boundaries or serving paths are separate |
| Google Tag Manager and ad tags | Low | Content changes frequently and cannot be pinned |
| Analytics and A/B testing tools | Low | Dynamic serving and SRI don't mix well |
| Module Federation remotes | Low to medium | Feasible but hash distribution and deployment management are hard |
| Regular Next.js chunks | Medium | Depends on the hosting setup and CSP requirements |
| Admin screens and personal-information input screens | High | Reduce external scripts, and use SRI on the fixed assets that remain |
So, should you add SRI to external CDNs after all? Within the scope of what I looked into, the answer is a conditional yes. Say you load JavaScript or CSS from an external origin, the URL is pinned to a specific version, and the same URL always returns the same content. If on top of that the CDN supports CORS and you can update the hash when you upgrade, add it as a rule.
If you come across a load like the following, think about pinning the version before you even get to SRI.
<script src="https://cdn.example.com/library/latest.js"></script>
Pin the version and then add SRI, and both the URL and the content are pinned.
<script
src="https://cdn.example.com/library/1.2.3/library.min.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>
Conversely, don't force SRI onto analytics scripts whose content changes frequently, tag managers, or ad tags. The same goes for widgets whose content varies per user, dynamically resolved remotes, and services that return different code per User-Agent. Those call for other defenses.
And SRI is not a contraption you drop in on its own and call it a day. As for priorities in practice, the realistic place to start is removing unnecessary third-party scripts. The safest script is the one you never load. On admin screens, payment screens, and personal-information input screens above all, you should question whether marketing tags and chat tools really need to be there.
Next, get HTTPS and CSP in order. HTTPS is a given, and narrowing load sources and destinations with CSP makes unauthorized script injection and data exfiltration harder. Then add SRI to fixed external resources. That's the territory where SRI is easy to apply and pays off well.
Beyond that, protect your npm dependencies and build process with lockfiles, dependency updates, auditing, and CI/CD protection. You need that regardless of SRI. Finally, monitor and isolate the dynamic third-party scripts that SRI can't cover, combining iframes, sandbox, CSP, change monitoring, and permission control.
The Fixed-File Assumption
Before looking into it, SRI struck me as "a slightly dated security feature where you just tack a hash onto external CDN tags." In reality, the problem SRI is trying to solve is still very much with us.
When you think about it, loading JavaScript from outside onto a web page is close to handing that origin the same privileges as your own page. An external script on your page can read the DOM, read form input, and access client data other than cookies. It can send requests to APIs, send data to external servers, and load yet more scripts. That's exactly why SRI's mindset of "allow only this exact content of this file," rather than settling for "it's a well-known CDN, so I trust it," makes sense.
On the flip side, the high-risk players on the modern web, such as Google Tag Manager, ads, analytics, A/B testing, and chat, change their content so often that SRI is hard to apply to them. SRI isn't rarely used because the technology is meaningless. It's rarely used because modern third-party scripts have drifted away from its core assumption of "loading a fixed file," or so I've come to see it.
That's the story of what SRI can and can't prevent, and where it belongs. SRI's value comes down to letting the browser verify that a resource fetched from a trusted origin really matches the content approved in advance. It works against CDN tampering, compromise of external origins, wrong files being served, and replacement at fixed URLs. It can't, however, prevent tampering with the HTML itself, XSS, npm package compromise, CI/CD compromise, or malicious official releases.
As for how to apply it: add it as a rule to fixed-version JS/CSS from external CDNs, and lower its priority for a typical SPA bundled in-house from npm. On admin and payment screens, cut third-party scripts first, and cover dynamic scripts that can't take SRI with CSP, isolation, and monitoring. And don't treat SRI as a substitute for security as a whole.
It isn't a feature every website absolutely needs, but where it fits easily, it's still a defense that buys a clear benefit at low cost. Then again, a tally does nothing just sitting in your pocket. What matters is which paths you trust and which stage's tampering you're trying to prevent, and whether you can explain that yourself.
References
- W3C Subresource Integrity
- WHATWG HTML Standard
- WHATWG Fetch Standard
- W3C Content Security Policy Level 3
- MDN: Subresource Integrity
- MDN: integrity attribute
- MDN: import maps
- MDN: modulepreload
- OWASP Third Party JavaScript Management Cheat Sheet
- web.dev: Why HTTPS matters
- Webpack Production Guide
- Vite Build Options
- Next.js Content Security Policy Guide
- Angular CLI ng build
- Laravel Vite
- Vue CLI Configuration Reference
- Cloudflare: Polyfill.io links replacement
- Codecov Bash Uploader Security Update
- GitHub Advisory: ua-parser-js
- GitHub Advisory: flatmap-stream
- ICO: British Airways Penalty Notice