CVE-2026-2005, CVE-2026-2006, and CVE-2026-2007 are now patched. All three are heap buffer overflows in PostgreSQL or its bundled extensions. The pgcrypto bug — the headline one — has been sitting in the tree since approximately 2005, which means it is older than the iPhone, Twitter, and (for some of you reading) your career. Two of the three were found by an autonomous AI code-analysis tool called Xint Code, entered into Wiz’s ZeroDay.Cloud contest in December 2025.

The interesting question is not “are AI tools good at finding bugs.” The interesting question is why a competent group of humans, with twenty years and a worldwide community to draw on, didn’t find these bugs first.

What the bugs actually are

The most serious of the three, CVE-2026-2005, is in pgcrypto’s PGP message handler. A crafted PGP message tricks the parser into copying more bytes than the destination buffer holds, and the overflow lands in heap memory that the attacker can — with some chaining — arrange to be useful. The exploit path requires that the attacker be able to load pgcrypto and call its decryption functions, which is a normal database-user privilege on most installations that use the extension at all. The end state is arbitrary code execution as the OS user running PostgreSQL.

CVE-2026-2006 is structurally similar — pgp_sym_decrypt, malformed UTF-8 sneaking past pg_mblen and pg_utf_mblen, out-of-bounds reads or writes. CVE-2026-2007 is in pg_trgm, the trigram extension, and is the same shape of bug in a different neighborhood.

In other words: three buffer overflows in C code that does parsing of attacker-controlled binary or string data. The most classic shape of bug there is. The kind of bug that fuzzing was supposedly built for.

Why these are hard to find

It would be cheap to say “well, pgcrypto is unloved” and walk away. That is partly true. pgcrypto sits in contrib/, it doesn’t get the same level of review as core executor code, and the people who care most about its correctness — security and compliance auditors — generally treat it as a black box rather than reading its sources. But that explanation isn’t sufficient. The PostgreSQL project does take security seriously. The PostgreSQL Security Team does triage things. And the bugs were technically reachable, technically straightforward, and technically — once you knew where to look — obvious. So why didn’t anyone look?

Three reasons, in order of how uncomfortable they are to say.

Crypto parsing is uniquely bad for human review. PGP messages have a recursive, length-prefixed, variant-tagged structure. The validation code is a state machine threading through nested buffers, and the correctness condition is not local: you cannot read the function that contains the overflow and decide whether it is safe. You have to track the invariant that some other function should have established about the bytes you are now copying. Humans are terrible at this. C is terrible at this. The two together are a guaranteed pipeline of latent buffer overflows for the next twenty years, with or without AI to find them.

Coverage-guided fuzzing struggles with format-specific protocols. AFL and libFuzzer and the rest of the modern fuzzing toolkit are excellent at finding bugs once you give them a corpus and a target. They are bad at navigating deeply nested, header-driven formats from random bytes. Most of the wall-clock fuzzing time on pgcrypto would be spent generating inputs that fail the very first PGP packet header check. The bugs are deeper in the parse tree than coverage-guided fuzzing reaches unaided.

Nobody owns these extensions. Not in a hostile sense. In a quiet sense. They are maintained, they get patches, they don’t have a single committer who wakes up in the morning thinking about how to break them. Compare against the executor, the planner, the buffer manager — components where the maintainer set is dense and adversarial in the productive sense — and you see the gap.

What Xint Code actually changed

Xint Code is described as an autonomous AI code-analysis tool. From the published writeup, it doesn’t fuzz. It reads code. It tracks tainted data — bytes that came from the network or from bytea arguments — through the parse-and-decrypt pipeline, and it flags places where a length check is missing or weakened. When it finds a candidate, it attempts to construct a proof-of-concept input that triggers the bug.

That is not magic. It is, structurally, what a careful human auditor would do, given infinite patience and no other obligations. The difference is that Xint Code has those things and the human does not. The careful human auditor we have all been waiting for is, it turns out, a moderately competent LLM-driven static analyzer running unattended.

I want to be careful here. The CVEs are real, the patches are real, the bug class is real, and the value of the find is real. But “AI finds twenty-year-old bug” is also exactly the framing that funds the next round of investment in this kind of tool, and the framing carries some load-bearing exaggeration. The bugs were not invisible. They were unattended. The novelty is not that something found them. The novelty is that something found them cheaply. The unit economics of “throw an autonomous agent at a contrib module for a weekend” are very different from “ask Mark Dilger to read pgcrypto carefully for a month,” even though the two might produce comparable results.

So what changes in the development process

The PostgreSQL project has, for good reasons, been cautious about pulling AI-assisted analysis into its security workflow. There is a legitimate concern about false positives wasting committer time, about the provenance of analysis results, and about the project being implicitly dependent on a proprietary tool to know its own vulnerabilities. None of that goes away.

What does go away is the argument that AI tools don’t find real bugs in mature C code. They do. The three CVEs are evidence. The right institutional response — and I would bet this conversation is already happening on the security team — is to run an Xint-class tool against contrib/ on a recurring basis and to triage what comes back. Not because the tool replaces human review, but because the tool is now demonstrably cheaper than human review at the specific task of finding length-check omissions in parse-and-decode code.

For everyone else: if you run a PostgreSQL deployment that exposes pgcrypto, apply 18.4, 17.10, 16.14, 15.18, or 14.23 immediately. The exploit path is short, the privilege requirement is low, and the bug class is the one that traditionally gets weaponized first. There is no good operational reason to be on a pre-May-14 release in front of attacker-controlled input.

And for the rest of contrib/: I’d assume someone, somewhere, is running similar tools against xml2, dblink, pageinspect, and a handful of others, and that there is going to be more news on this beat before the year is out. Plan accordingly.