
Software security fixes are both bug closers and maps: they show where a given bug used to live and how the developer chose to close it. Narrowing down the fix so that it only blocks the reported case can point the next attacker toward undefended gaps around the repair.
Terra Security noticed this in our own work this past year: a fix would ship, a bypass would be found, and another fix would go out. Worried this was sample bias, we looked at every published CVE record and every GitHub-reviewed advisory for one pattern: a fix ships, and a later advisory says it was incomplete or could be bypassed.
The data backed up our hunch. Broken fixes have been reported for years at a low, steady rate until 2026, when the share of open-source fixes on GitHub later reported broken rose about eightfold.

The CVE record database gives much wider coverage than our GitHub data and shows the same jump in the same year. CVE records often read as a new, unrelated bug when only GitHub's advisory says the earlier fix failed, so CVE-only analysis would undercount these cases.
What we found
1. Fixes for exploited bugs break about four times as often
Bugs on CISA's known-exploited list have their fixes later reported broken about four times as often as the same vendors' other bugs. The likely reason is attention: exploited bugs draw more researchers, who study the patch and find what it missed.
The upshot is that the "patch and move on" habit is a bad one, especially for the bugs that matter most.

2. Blocklist-style fixes break the most
There are bug classes where the usual fix is a reject-list of inputs (hostnames, paths, object keys). Server-side request forgery and prototype pollution are many times overrepresented among broken fixes, against all CVEs. The reason is simple: if the blocklist doesn't foresee every encoding of a bad input, the attacker only needs to find one. We did these calculations by bug class alone, not by how each fix was written.

3. In the Linux kernel, fixes cause new vulnerabilities
Kernel CVE records list both the introducing commit and the fixing commit, so we can see the overlap. In fact, 3.2% of kernel CVEs were introduced by the fix for another CVE, and about 10% in busy subsystems like fs/smb and net/sched. It's very rare that a new record references the old one, so any tool that parses CVE text has a blind spot.

Three examples
Roundcube: one bug, four CVEs in five months
In March 2026, Roundcube fixed a Server Side Request Forgery (SSRF) bug (CVE-2026-35540) by blocking links to private addresses. The check caught 127.0.0.1 only and missed alternate forms of the same IP (2130706433, 0x7f000001 and 127.1), and it also missed DNS names resolving to the address. Gaps in this blocklist were closed with 3 more CVEs in May, July, and August.
Linux af_unix sockets: each fix caused the next bug
A 2023 change let out-of-band socket messages carry file descriptors that the kernel's garbage collector didn't track. That was CVE-2024-26676. The fix could hang the kernel (CVE-2024-26780), and the fix for the hang got stuck on one list ordering (CVE-2024-26750).
Microsoft: exploited, patched, bypassed, exploited again
CVE-2026-21510 was a Windows Shell vulnerability that APT28 was exploiting in the wild; Microsoft patched it in February 2026. Akamai noticed the patch was still bypassable with a crafted Control Panel item that made Windows contact an attacker's server, leaking the user's NTLM hash. Microsoft fixed this in April with CVE-2026-32202, also on CISA's exploited list. The new advisory never mentions the old CVE.
What this means for defenders
A patch that only blocks the reported input can give the impression the bug is addressed even if it's still there in the underlying code. It functions as a map for attackers, marking out both vulnerable code and what the defender thought the bug was.
Looking just outside the diff (another encoding, another address range, another path into the same function) is one of the cheapest forms of bug hunting. We believe a growing share of attacker effort, and AI tokens, goes into exactly this.
Diff-hunt your own fix before shipping it, certainly before any attackers do. As you look at any fix, consider:
- Does it fix the root cause? A fix that only blocks the reported payload isn't done. With a blocklist, dig harder.
- Does it cover the whole bug class? Try variants the advisory doesn't talk about, and look for other paths to the same code, other callers of the same function.
- Does it break something else? A rushed patch in sensitive code should still meet the same review bar as any other change there.
The same goes for patches you install. If a vendor fixes an exploited bug, assume someone is reading the patch for a way around it. Keep testing even after your scanner comes back green.
If you're unsure your last fix closed the hole, talk to us at terra.security.






