Patch Forecast
Yellow warning
Plan into this sprint.

CVE-2026-96633 · GHSA-6vfx-w7q3-42gq

AdminNeo SQLite Database-List Drop Arbitrary File Deletion

Risk score
54/100
CVSS
8.1 v3.1
Published
30 Oct 2026

Open in the live forecast Today's forecast

What to know

What it is
AdminNeo allows an authenticated SQLite-mode user to delete arbitrary files writable by the PHP process through the database-list drop action. The SQLite driver validates file extensions when creating or renaming databases, but the database-list drop path passes submitted db[] values directly to unlink(). Originally r…
Affected
adminneo-org/adminneo (composer) < 5.5.1
Fix
Upgrade adminneo-org/adminneo to 5.5.1 or later.
Exploitation
No known exploitation

Story map

Story map: adminneo-org/adminneoTHE FLAWSTHE FIXCVE-2026-96633AdminNeo SQLiteDatabase-List Drop ArbitraryFile DeletionCVSS 8.1CVE-2026-96631AdminNeo has Cookie AttributeInjection via UnsanitizedX-Forwarded-Prefix in…CVSS 8.2CVE-2026-96632AdminNeo Vulnerable to XSS viaRogue MySQL Server VersionString (CSP Nonce Bypass)CVSS 8.2CVE-2026-59978AdminNeo: version-cache arrayinjection causes persistentdenial of serviceCVSS 7.5Upgrade…5.5.0or later on your release lineWho is exposed{'products': ['AdminNeo'],'packages': [{'ecosystem':'composer', 'name':'adminneo-org/adminneo','vulnerable': '>= 4.6.0, <…AMBER · PATCH THIS WEEKadminneo-org/adminneoAdminNeo versions 4.6.0 to 5.5.0are vulnerable to cookieattribute injection via the`X-Forwarded-Prefix` HTTPheader. An attacker can injectarbitrary cookie attributes,allowing them to expand the…Where it standsPublic proof of conceptCONNECTS TOSame weaknessCWE-73 (CWE-73)71 other warnings in 30 days →
Story map: the flaws, the fix, how it unfolded and what it connects to. Boxes link to the record or article.

At a glance

adminneo-org/adminneo: Amber, patch this week. AdminNeo versions 4.6.0 to 5.5.0 are vulnerable to cookie attribute injection via the `X-Forwarded-Prefix` HTTP header. An attacker can inject arbitrary cookie attributes, allowing them to expand the cookie scope to an attacker-controlled domain.

The flaws

  • CVE-2026-96633: AdminNeo SQLite Database-List Drop Arbitrary File Deletion (CVSS 8.1)
  • CVE-2026-96631: AdminNeo has Cookie Attribute Injection via Unsanitized X-Forwarded-Prefix in Set-Cookie Headers (CVSS 8.2)
  • CVE-2026-96632: AdminNeo Vulnerable to XSS via Rogue MySQL Server Version String (CSP Nonce Bypass) (CVSS 8.2)
  • CVE-2026-59978: AdminNeo: version-cache array injection causes persistent denial of service (CVSS 7.5)

The fix

Upgrade adminneo-org/adminneo: 5.5.0 or later on your release line

Who is exposed: {'products': ['AdminNeo'], 'packages': [{'ecosystem': 'composer', 'name': 'adminneo-org/adminneo', 'vulnerable': '>= 4.6.0, < 5.5.1'}], 'versions': ['4.6.0', '5.5.0', '5.5.1']}

Where it stands

  • Public proof of concept

Connects to

Why it is Yellow

  • CVSS 8.1 high
  • On your watchlist: Composer

Affected packages

PackageEcosystemVulnerableFixed in
adminneo-org/adminneocomposer< 5.5.15.5.1

References

Original description

## Summary AdminNeo allows an authenticated SQLite-mode user to delete arbitrary files writable by the PHP process through the database-list drop action. The SQLite driver validates file extensions when creating or renaming databases, but the database-list drop path passes submitted `db[]` values directly to `unlink()`. Originally reported by @slpoiuewalspoid-dotcom in Adminer: https://github.com/vrana/adminer/security/advisories/GHSA-6pg3-chwq-wgqc ## Impact An authenticated AdminNeo SQLite user with a valid CSRF token can submit an arbitrary relative file path in the database-list `db[]` field. If the PHP process can delete that path, AdminNeo unlinks it even when the file is not a SQLite database. ## Root Cause The database-list page accepts selected database names from the POST body and calls `drop_databases()`: ```php if ($_POST["db"]) { queries_redirect(substr(ME, 0, -1), lang('Databases have been dropped.'), drop_databases($_POST["db"])); } ``` In SQLite mode, `drop_databases()` attaches an in-memory database and unlinks each submitted path directly: ```php function drop_databases($databases): bool { Connection::get()->close(); // to unlock file, doesn't work in PDO on Windows foreach ($databases as $db) { if (!@unlink($db)) { Connection::get()->setError(lang('File exists.')); return false; } } return true; } ``` The same SQLite driver protects create and rename operations with `check_sqlite_name()`, which requires a `.db`, `.sdb`, or `.sqlite` extension: ```php function check_sqlite_name($name) { // avoid creating PHP files on unsecured servers $extensions = "db|sdb|sqlite"; if (!preg_match("~^[^\\0]*\\.($extensions)\$~", $name)) { Connection::get()->setError(lang('Please use one of the extensions %s.', str_replace("|", ", ", $extensions))); return false; } return true; } ``` The drop path does not apply an equivalent extension check or bind the submitted path to a known listed SQLite database. ## POC ### 1. Start a complete AdminNeo application Build and start AdminNeo from the audited source using the official standalone Docker image shape. The validation image copies the audited source tree into `/var/www/html` and starts Nginx HTTP server. Log in through the SQLite entry point using a SQLite database path `poc.sqlite`. ### 2. Prepare a writable target file Place a non-database file under a location writable by the AdminNeo PHP process. The validation used: ``` /var/www/html/poc-delete-target.txt ``` The same directory also contained a SQLite database: ``` /var/www/html/poc.sqlite ``` ### 3. Submit the database-list drop request Use the authenticated session and live CSRF token, but submit the non-database path as the selected database: ```http POST /?sqlite=&username= HTTP/1.1 Host: <adminer-host> Cookie: <authenticated-session> Content-Type: application/x-www-form-urlencoded db[]=/var/www/html/poc-delete-target.txt&all=&drop=Drop&token=<live-csrf-token> ``` The request reaches `drop_databases($_POST["db"]),` and SQLite `drop_databases()` calls `unlink()` on the submitted non-database path. After the request, the `poc-delete-target.txt` was deleted. ## Suggested Fix Apply the same target validation used by SQLite create/rename before deleting database files. At minimum: - Reject paths whose basename does not end in `.db`, `.sdb`, or `.sqlite`. - Bind `db[]` values to databases returned by AdminNeo's database listing instead of trusting submitted paths. - Resolve paths before deletion and reject traversal outside the expected SQLite database directory. - Consider requiring the current selected database path for delete operations instead of accepting arbitrary submitted file paths.

Last activity 30 Oct 2026. Patch Forecast updates every hour.