CVE-2026-50006: unauthenticated arbitrary file write in anyquery server mode
CVE-2026-50006 turns SQLite ATTACH DATABASE into an unauthenticated file-write primitive in anyquery server mode. We reproduced it and verified the 0.4.5 fix.
CVE-2026-50006 is an unauthenticated arbitrary file write in anyquery server, published as GHSA-xrcf-6jh3-ggvx on July 14, 2026. The bug sits at an uncomfortable boundary: anyquery exposes a SQLite-backed query engine over the real MySQL wire protocol, then lets certain SQL statements pass straight to the underlying driver. One of those statements is ATTACH DATABASE, and in SQLite that is enough to create a real file on disk.
The fixed version, 0.4.5, was tagged and released on June 9, 2026, five weeks before the CVE was published. This was not an Emphere patch, and we are not claiming to have discovered the bug. What we did was read the vulnerable path, read the fix, and then verify both with a red run, a green run, and a control run that rules out coincidence.
Evidence status
The vulnerable path
The server handler has a hardcoded prefix table in namespace/mysql_handler.go. Statements matching those prefixes are sent down the ExecContext path rather than being treated as normal queries. In the vulnerable version, ATTACH DATABASE is one of those prefixes, and there is no authorization check between the MySQL client and SQLite.
That dispatch table is still present at current HEAD, which matters. The patch does not make the MySQL handler smarter, and it does not rely on every call site remembering to filter dangerous SQL. The fix works lower in the stack, where SQLite can still see the operation after the statement has been parsed.
| Step | What happens |
|---|---|
| Connect | anyquery server accepts the MySQL client when AuthFile and Users are empty, which is the default. |
| Attach | The client sends ATTACH DATABASE '<path>' AS x, routed to SQLite through ExecContext. |
| Create | If <path> does not exist, SQLite creates it as an on-disk database file. |
| Write | CREATE TABLE x.t(a); INSERT INTO x.t VALUES('...') writes attacker-controlled content into that file. |
| Reuse | Targets such as cron, sshd, or a PHP web root can tolerate the SQLite header before the line they care about. |
The advisory PoC uses this exact property against /etc/cron.d/pwn, ~/.ssh/authorized_keys, and a PHP webshell in a web root. There is no second bug in the application layer that turns SQL into code execution. The administrative SQL command is the file-write primitive.
The obvious fix is a trap
The easy reaction is to block ATTACH DATABASE outright. That would close the exploit, but it would also break legitimate operator workflows, including in-memory attaches and intentionally allow-listed on-disk attaches. The important distinction is not "ATTACH is bad." It is "untrusted network clients should not be able to attach arbitrary local paths."
| Fix shape | Security result | Engineering result |
|---|---|---|
| Leave the dispatch table alone | Fails, unauthenticated file write remains reachable | No compatibility cost |
Block every ATTACH DATABASE | Closes the primitive | Breaks legitimate in-memory and operator-approved attach use cases |
| Authorize attach paths inside SQLite | Closes arbitrary file write by default | Preserves harmless and explicitly allowed attach behavior |
The 0.4.5 patch takes the third route. It registers a SQLite authorizer after trusted internal setup has already run, then denies on-disk attaches unless server restrictions explicitly allow them and the resolved path is inside an allowlist. That is the right shape for this bug: narrow, path-aware, and default-deny for the network listener.
The fix
The fix commit is 27f84fc168310455eaf81ec4ba87eed20298670c, titled "Add sandboxing to remediate CVE-2026-47253 and CVE-2026-50006." The commit message names two CVEs, but the sandbox it adds actually closes several related issues in the same server surface. Assurance independently re-drove only CVE-2026-50006; the others are covered by the maintainer's own passing sandbox tests, not by our exploit reproduction.
The key behavior is in AllowAttachPath. In-memory databases are allowed, empty paths are rejected, and on-disk attaches are denied unless AllowAttach is set and the final local path passes the directory restriction check. That keeps the useful SQLite feature without leaving a network-exposed file-write primitive behind.
For anyquery server, sandboxing is on by default and can be disabled with --no-sandbox. For local CLI use, sandboxing is opt-in with --sandbox. That split is the important operational default: a local CLI user is usually the operator, while a MySQL-compatible network listener has to treat its client as untrusted unless authentication and network exposure prove otherwise.
How we verified it
Assurance ran the vulnerable and patched targets as real OS processes, connected with a real MySQL wire client, and let real SQLite create real files on disk. No handler was mocked, no database layer was stubbed, and the exploit was not reduced to a unit test around the authorizer. The red run proves exploitability in 0.4.4; the green run proves the default 0.4.5 behavior denies the primitive; the --no-sandbox control proves the authorizer is the difference.
Evidence status
We also checked the regression surface against 0.4.4. The full suite had zero new failures in 0.4.5 compared with the vulnerable version. Three failures appeared in both versions and were environmental: a stale remote fixture and a go-sql-driver/go1.24 argument-count quirk, unrelated to the sandbox patch.
Scope
The 0.4.5 sandbox closes a cluster of anyquery server issues at once. We took the most severe, the unauthenticated ATTACH DATABASE file write that reaches remote code execution, and proved it end to end on real binaries: a red run, a green run, and a control. The rest of the cluster is closed by the same authorizer and the maintainer's passing sandbox tests: a clear_plugin_cache path traversal that deletes directories (CVE-2026-47253), and local file read and SSRF through the read_* virtual-table modules (CVE-2026-54629, CVE-2026-54628). We scoped the proof to the file-write primitive deliberately, because it is the one that turns a query engine into code execution.
Two points of precision. The real exposure is server mode with no --auth-file reachable by an untrusted client, not the localhost default bind, which predates the fix and is unrelated to it. And run the latest release rather than 0.4.5 specifically: 0.4.6 later closed a separate file-URI sandbox bypass on the read path (repository advisory GHSA-j4wj-p47h-f9cc), a different surface from the ATTACH authorizer verified here.
Close
"Upgrade to 0.4.5" is the right operational advice. It is not, on its own, proof that the patch holds, and that proof is what makes the advice worth trusting. For CVE-2026-50006 it reduces to one statement: before 0.4.5, an unauthenticated ATTACH DATABASE could create a file anywhere the process could write; after 0.4.5, the same statement is denied before a file exists.