SQLite Critical CVEs or LLM Slop? jFrog Investigates
jFrog verified six 'critical' SQLite CVEs and found fabricated functions, impossible line numbers, and PoCs that crash nothing — with red flags you can check.

A 9.8-critical CVE sitting in NVD feels like verified fact — surely someone checked it. jFrog checked six of them, all filed against SQLite, and found functions that never existed, line numbers past the end of the file, and proof-of-concepts that crash nothing.
Source
SQLite Critical CVEs or LLM Slop?
By: jFrog (Afek Berger, JFrog Security Research)
Published: Jul 30 2026
Type: Security research
This one is worth keeping because it demonstrates, step by step, how to verify a vulnerability advisory instead of trusting the pipeline that delivered it — and because the red flags it identifies take minutes to check and would have caught every one of these fakes.
What verifying six fake CVEs looks like
Some vocabulary first, because the story turns on it. A CVE is a public record of a claimed vulnerability in a specific product; CVSS is the 0–10 severity score attached to it; NVD is the US National Vulnerability Database that collects and enriches CVEs; a PoC is a proof-of-concept — input meant to trigger the bug. A use-after-free (UAF) is a memory bug where code keeps using a pointer after its memory has been freed.
The events: a newly created GitHub account published a batch of SQLite vulnerability advisories, part of a run of 50+ CVEs that jFrog came to believe were machine-generated, all except one. NVD quickly flagged them critical, and CISA’s enrichment program agreed. Then jFrog checked. The cited code didn’t exist in the claimed versions or pointed at unrelated logic. The PoC payloads didn’t trigger so much as a crash. None of the issues appeared on SQLite’s own advisory page, which the researchers call the gold standard for tracking real SQLite vulnerabilities. Run through GPTZero, the advisories read as AI-generated — and pasting all of them into one file trips AI-content detectors outright. One CVE’s Red Hat score had already slid from 10.0 critical to 7.6 high between two checks days apart.
The methodology is refreshingly ordinary, and that’s the point. Clone the official SQLite repository at the exact tags named in the advisories (3.41.0, 3.51.2, 3.51.3). Compare each claimed vulnerability against the actual source. Compile the official releases in isolated containers, feed each PoC’s SQL verbatim into the binary under AddressSanitizer — a compiler instrumentation that reports memory errors — and watch for the promised crash. Then audit the NVD and GitHub Advisory (GHSA) metadata for contradictions.
What that produced, in the advisories’ own order: the first “critical” (9.8) blamed a UAF triggered via exprComputeOperands(), a function that didn’t exist in 3.41.0 at all — it was added in mid-2025 — while the accused sqlite3ReleaseTempReg() merely recycles register indices into an array, freeing no heap memory, which makes a UAF impossible by construction. The second (9.8) claimed a patch in 3.51.3 that a diff of 3.51.2 versus 3.51.3 disproves outright: src/expr.c didn’t change, and the back-reference pointers the advisory described don’t exist in those structures. Its PoC isn’t even valid SQL and dies at the parser. The third (9.1) cited two line numbers in expr.c that turn out to be a comment and a memory allocation — nothing to do with the claimed dangling pointer. The fourth (8.8) leaned on jsonBlobEdit(), introduced long after 3.41.0 as part of the JSONB work; its PoC fails immediately on malformed JSON and never reaches the supposedly vulnerable code. The fifth (7.5) cited lines 3555 and 3575 of json.c — a file that is only 2706 lines long in that version. The sixth (7.5) reported a one-argument call to a function whose real signature takes two, and missed that SQLite nulls the pointer immediately after freeing it.
So how do fakes get this far? The CVE submission form is public and verifies no identity; anyone can file a description and propose a score. The system’s old safety net was NVD’s manual analysis of incoming records, but that broke in February 2024, when a surge in reports forced NIST to pause deep analysis. CISA and other authorised publishers stepped in partially, leaving a fragmented pipeline with a backlog. No step anywhere requires a PoC or a reproduction, so a convincing fake can end up in GHSA, downstream databases, and enterprise scanners without ever being run once.
The audit widened from there: 55 advisories from the same account, 54 completely fabricated, one real bug wrapped in unverified metadata. jFrog reported all of this to GHSA, Red Hat, and NVD to get the records corrected. The red flags generalize beyond this account: no mention on the vendor’s own security page, no commit hash or pull request anywhere in the references, metadata contradictions like empty CPE product definitions or version ranges that conflict with the write-up, and code references to functions or lines that don’t exist in the claimed version.
The stakes aren’t just noise. Teams burn hours investigating and patching phantoms, and scanner-driven workflows that auto-prioritize “critical” tickets amplify the cost. The post ends on the uncomfortable near-future case: an AI triage agent handed a fabricated CVE may diligently locate the non-existent function and generate a patch for code that isn’t there.
My take
What the writeup reveals, without quite saying it, is that verification was cheap — a git checkout, a grep, a compile, a test run. The expensive thing is that nobody in the pipeline is positioned to do it: submitters don’t have to, NVD stopped being able to, and downstream consumers assume someone else did. LLMs didn’t break this system; they made it economical to flood a system that already ran on trust. Which flips the practical lesson: the answer isn’t to distrust CVEs generally, but to notice that the four red flags — vendor corroboration, commit links, metadata consistency, code existence — are mechanical checks a triage script can run before a ticket is ever opened.
Where this is useful
- Security and DevOps teams with SLAs like “critical CVE patched in 48 hours” — a verification gate belongs in front of that clock.
- Anyone triaging advisories against embedded, ubiquitous libraries like SQLite, where a fake critical is maximally scary.
- Maintainers of smaller open-source projects, who have no jFrog watching their name and are the natural next targets.
- Teams building AI-assisted vulnerability triage — the red-flag checks should run before the agent is allowed to propose a fix.
Apply this: The next time a critical CVE lands for a dependency, spend ten minutes before opening a ticket: check the vendor’s own advisory page, hunt for a fixing commit hash, and run the PoC in a container. If any of the three come up empty, treat the CVE as a claim, not a finding.
What I want to remember
Remember: A CVE is a claim, not a finding. Check that the cited code exists at the cited version, find the patch commit, and run the PoC — ten minutes of grep beats a day spent patching a ghost.