AngularJS, Lodash, Moment: the abandoned libraries still on live sites
Open the console on your own site and type _.VERSION. If it answers 4.17.4, you are shipping a Lodash build that stopped getting security fixes years ago. The page still renders. Every test still passes. None of that tells you whether the people who used to patch its holes are still around.
So how many libraries on your live pages are end of life, and do you actually know which ones they are? Most teams can't name a single one, because nothing about a running page advertises that its maintainers have walked away.
End of life means no more releases. Not "slower releases." None. When a vulnerability is found in an end-of-life library, there is no patch coming, ever. The advisory gets published, the exploit gets written, and your page keeps serving the same unpatched bytes it served yesterday. The maintainers have moved on. The attackers have not.
The usual suspects
A handful of these show up on live sites constantly, long after their owners told everyone to stop.
AngularJS (the 1.x branch, not modern Angular) hit end of life on December 31, 2021. Google said it plainly: no more patches, including security patches. There are known XSS and sandbox-bypass issues in old 1.x builds, and a {{ }} expression that reaches user input is a classic injection point. The fix is a migration, not an upgrade, which is exactly why so many sites are still on it.
Moment.js is in maintenance mode and the project itself recommends you stop using it for new work. It carries a known ReDoS issue (CVE-2022-31129) where a crafted date string can hang the thread parsing it. It still works on every page it's on. That's the trap.
Lodash had a prototype-pollution class of bugs (CVE-2019-10744 in defaultsDeep, among others) that let crafted input modify Object.prototype and change how unrelated code behaves. Versions before 4.17.12 are exposed. Plenty of bundles still ship an old 4.17.x.
Bootstrap 3 is end of life and shipped XSS via data attributes (CVE-2019-8331 and friends). Handlebars had a prototype-pollution and template-injection run that landed real RCE in some setups before 4.x. None of these are obscure. They're the libraries a 2018 starter template pulled in by default.
What an attacker actually does
End of life changes the calculation in the attacker's favor, and they know it.
With a maintained library, finding a bug starts a race: they have until you update. With an end-of-life one, there is no race. The bug is permanent. So these libraries are worth scanning for, and people scan for them at scale. A crawler fingerprints the version string in your JavaScript, matches it against a list of unpatched CVEs, and flags your domain as a soft target before a human ever looks.
What happens next depends on the bug. Prototype pollution in old Lodash can quietly change the behavior of code that never touched the attacker's input directly, which is how a "harmless" utility turns into a foothold. A template-injection bug in old Handlebars or AngularJS can become script execution in the visitor's browser, with all the consequences that carries: stolen cookies, hijacked sessions, a swapped-out form. If your session cookie also lacks HttpOnly, the path from "old template engine" to "logged in as your user" is short.
The unifying point is that none of these will alert you. The page renders. The library does its job. The only signal is the version string sitting in plain sight in the bundle you ship to everyone.
So what are you actually serving?
You can't fix what you can't see, and the version is usually visible from the console.
angular.version.full // "1.7.9"
_.VERSION // "4.17.4" (Lodash)
moment.version // "2.24.0"
$.fn.tooltip.Constructor.VERSION // Bootstrap
Run each in your site's browser console. undefined means it isn't loaded globally, but check the page source for the script tags anyway, since bundlers often hide these inside a single minified file rather than on window. When you find a version, look it up: is the project end of life, and is your version below its last safe release? That two-line check is the whole job, and almost nobody does it after the initial build.
The same neglect produces the classic outdated jQuery version with a known XSS hole, so check that while you're in the console.
How to handle it
There's no single patch, because the libraries are different and so are the fixes. The decision tree is short.
If the library has a maintained successor, migrate. Moment to a modern date library. AngularJS to Angular or something else entirely. This is real work, and pretending otherwise helps no one, but it's the only path that ends the exposure.
If you just need a newer build of the same library, bump the version and rebuild. Lodash 4.17.4 to 4.17.21 is one line in your lockfile and a fresh build. Bootstrap 3 to a current major is more involved but bounded.
If you don't actually use it, remove it. A surprising amount of dead weight rides along in bundles because a dependency pulled it in years ago and nothing prunes it. Every library you delete is one you never have to patch.
The list of abandoned libraries you're still shipping is the one most teams have never seen, and it takes a couple of minutes to produce. SurfaceCheckr fetches your pages, fingerprints the library versions in the JavaScript you serve, and flags the ones that are end of life or below a known CVE line, exactly the way a hostile crawler would. Everything we use is already in the bytes you hand to every visitor, so there's nothing to install and no backend to touch. We report the version and the matching advisory. We won't claim to know whether a specific vulnerable function is reachable through your particular UI, since we read from outside and don't drive your app or log in. Tracing reachability is a job for a code review. The version strings, though, we can hand you today.
Find it before someone else does.
Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what's reachable from outside.