Skip to content
AI-Assisted Security4 min read

Datasette's Security Patch Shows What an AI-Run Audit Actually Looks Like

Datasette 1.0a39 and 0.65.4 close a batch of permission-bypass bugs found via a week-long audit that ran Claude Fable 5.1, GPT-5.6 Sol, and GPT-6 Astra against the codebase in parallel with human reviewers.

By TRAGenX Desk

Share

Datasette, the open-source tool for publishing and exploring SQLite databases, put out two security releases on the same day: 1.0a39 for the alpha line and 0.65.4 for the stable branch. Maintainer Simon Willison was direct about who should care: anyone running a Datasette instance on the public internet, especially one that mixes public and private tables behind an authentication layer.

What actually broke

The 1.0a39 changelog reads like a tour of the places permission checks quietly fall apart in a system built around dynamic SQL. Table and view permission checks weren't accounting for SQLite's case-insensitive naming. Full-text-search index tables could be queried without permission to view the source table they indexed. The internal sqlite_stat1sqlite_stat4 tables — metadata SQLite keeps for its query planner — weren't denied by default, which matters because that metadata can leak information about a private table's contents and structure. ?_through= filters and foreign-key lookups could resolve relationships through tables a user wasn't supposed to see at all.

None of these are dramatic on their own. Each is a narrow seam where a permission check that guards the obvious path — "can this user view this table" — doesn't get re-applied on a secondary path into the same data: a stats table, a search index, a joined foreign key. That's the general shape of a permission bug in any system with more than one way to reach the same row, which is most systems with joins, caches, or derived views.

The audit process is the more interesting part

The fixes started from two independent reports — one from Sevban Dönmez, one from Alex Garcia. From there, Willison and Garcia ran what they described as an extensive audit using three different frontier models — Claude Fable 5.1, GPT-5.6 Sol, and GPT-6 Astra — then spent close to a week collaborating on and reviewing the resulting fixes. Willison and Garcia split the work so one person wrote automated tests for an issue while the other implemented the fix, meaning every bug had two separate humans plus multiple independent models look at it before it shipped.

That workflow is worth naming because it's not "ask an AI to find bugs and ship whatever it says." It's cross-vendor models as independent reviewers, human authorship of the regression tests that prove the fix actually closes the hole, and a second human on the fix itself. It's also why the team held back some of the proof-of-concept tests from the public repo — patching first, publishing exploit detail later, to give self-hosted instances time to upgrade before the exact mechanics are public.

Why builders outside the Datasette ecosystem should read the changelog anyway

  • Permission logic on top of a query engine is a recurring failure class. Any product exposing SQL, GraphQL, or a query DSL over row-level or table-level permissions should assume secondary access paths — joins, search indexes, metadata endpoints, cache layers — need the same enforcement as the primary read path, not an inherited assumption of safety.
  • Multi-model review catches different things than single-model review. Running Claude, GPT-5.6, and GPT-6 in parallel against the same codebase surfaced issues that two human reporters had already flagged independently — the models weren't a replacement for the reports, they were how the maintainers scaled from two known issues to a full audit.
  • Disclosure timing is a separate decision from patch timing. Shipping the fix and withholding the exploit-proving tests is a deliberate, defensible middle ground between silent patching and full immediate disclosure.

If you operate any data-facing tool with mixed public/private access — which describes a lot of fintech dashboards, trading tooling with per-tenant data, and internal analytics products — the practical move is the boring one: update, and specifically check whether your own permission model has a sqlite_stat-shaped blind spot, somewhere a secondary path (search, joins, metadata, cache) reaches data the primary path correctly protects.

FAQ

Frequently asked questions

Do I need to upgrade if I'm running Datasette privately, not on the public internet?
The maintainers frame the risk as specific to instances hosted on the public internet that mix public and private tables under authentication. A fully private, single-tenant instance is lower risk, but upgrading to 1.0a39 or 0.65.4 costs little and removes the question.
Were any CVE identifiers assigned to these Datasette issues?
Simon Willison's announcement and the linked changelogs do not cite CVE numbers; the fixes are described and tracked through the project's own changelog entries for 1.0a39 and 0.65.4.
What does 'coding agent security audit' mean in practice here?
Per Willison's account, Claude Fable 5.1, GPT-5.6 Sol, and GPT-6 Astra were used to audit the codebase for vulnerabilities, but the resulting fixes went through a week of human collaboration and review, with one maintainer writing tests while the other implemented each fix — the models augmented, rather than replaced, human sign-off.

Sources

Share

Read next