You can't bug fix your way out of the vulnpocalypse · Alex Gaynor
Alex Gaynor
Hi, I'm Alex. I'm a software resilience engineer. I care about building systems that work. I've worked for the government, in the private sector, and on open source. I'm based in Washington, DC.
© 2026. All rights reserved.
You can't bug fix your way out of the vulnpocalypse
Wed, Jul 15, 2026<br>(I work for Anthropic.)
One of the most important (and hardest!) questions for a security engineer to answer is “how many vulnerabilities exist in this code base”. You can know how many vulnerabilities you are aware of but haven’t patched yet. You might be able to do some arithmetic and estimate based on historical vulnerability time between introducing and discovery how many vulnerabilities exist, but are undiscovered, but that’s harder. Despite the inherently high level of uncertainty in answering just how many vulnerabilities exist, but are unknown, we all have a tendendecy to assume the rate of newly discovered vulnerabilities yesterday will also be true tomorrow. But some days you wake up and discover you’re no longer in Kansas. I remember when coverage-guided fuzzing (AFL and libFuzzer) got good enough that basically anything you could make parser-shaped was sure to produce a fair number of vulnerabilities. And now the AI vulnpocalypse has arrive, and for good measure it can also produce working exploits.
The recipe for a vulnpocalypse is a new technological innovation enables (or indirectly results in) finding a very large number of vulnerabilities in pre-existing software, which renders all previous assumptions and beliefs about the volume of extant vulnerabilities incorrect. When the vulnpocalypse hits, companies, open source projects, and software consumers are saddled with the task of identifying, triaging, fixing, distributing, and patching at a massively accelerated pace. Because there are so many vulnerabilities, existing processes break down. It ceases to become possible to fix all of the vulnerabilities with the pre-existing resource allocations and procedures.
This pattern – of new technological innovation upsetting core assumptions and requiring new approaches – is an example of what the literature calls “fundamental surprise”, and some friends of mine wrote a book about this. The failure mode of a vulnpocalypse is that the pile of vulnerabilities grows too tall, the triage process falls too far behind, open source maintainers burn out, and fixing the vulnerabilities becomes an exercise in random sampling and praying that the missed vulnerabilities don’t get exploited. Some teams double down on fixing the vulnerabilities one by one, driving out other types of projects they could work, and simply trying to patch anything they can find until they reach the status quo ante vulnerability equilibrium. These are really two sides of the same coin, simply with different levels of success.
Fortunately, there’s a better way. It begins with the recognition that a huge volume of vulnerabilities have substantially the same shape and proximate cause, and are amenable to systemic fixes. Not every vulnerability, but a lot of them.
Many years ago, I was pulled in to assist a team who was dealing with their own personal vulnpocalypse. It was an old VB Script codebase, a few hundred thousand lines of code, and a team of developers in maintenance mode. It was the kind of codebase where literally every SQL statement was vulnerable to SQL injection and every single variable incorporated into the HTML was an XSS vulnerability. There were other vulnerabilities as well, but by sheer volume, XSS and SQLi were easily 90%+ of them.
The pattern of SQLi was a common one in older applications: every page had its own bespoke code for opening a database connection and SQL was hand-crafted with string concatenation. The approach to fixing this was not to hand review every SQL query for whether it was vulnerable, it was to introduce a new SQLExecute function which took a SQL query and an array of parameters, and handled the query correctly. Then every single SQL query in the codebase was migrated to SQLExecute (many by a simple regular expression). Afterwards, a simple rule ensured there would be no regressions: it was illegal to execute a SQL query in any other way besides calling SQLExecute with a string literal, a rule that could be trivially enforced in CI. The net result was fixing thousands of vulnerabilities in a matter of a week or two, and the vulnerabilities staying fixed, and not being reintroduced.
This pattern of restricting a codebase to only safe patterns is not a novel one. To prevent XSS, Django’s templates automatically HTML escape any variables interpolated into a template, and React distinguishes between textual content and markup. It’s memory safe languages' approach to preventing buffer overflows and use-after-free vulnerability. Unfortunately,...