GHSA-2cwr-gcf9-pvxr Magento LTS has Weak API Session ID — Predictable MD5 of Time-Derived Inputs
Affected Version: OpenMage LTS ≤ 20.16.0 (confirmed on `20.16.0`)Affected File: `https://github.com/OpenMage/magento-lts/blob/main/app/code/core/Mage/Api/Model/Session.php` – `start()` methodSummaryThe XML-RPC / SOAP API session ID is generated using an outdated, time-based construction rather than a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG):All inputs to the MD5 hash are time-derived and non-secure:| Input                      | Value                                             | Predictability                         |
|----------------------------|---------------------------------------------------|----------------------------------------|
| `time()`                   | Unix timestamp (seconds)                          | Fully predictable                      |
| `uniqid('', true) prefix`  | `sprintf('%08x%05x', $sec, $usec/10)`             | Highly predictable via network timing  |
| `uniqid('', true) suffix`  | `php_combined_lcg()` decimal float                | Process-state dependent (`getpid() ^ time()`) |
| `$sessionName`             | `null` (empty) — called without arg               | Constant                               |Because the resulting digest relies entirely on the timestamp and the PHP internal LCG state, the effective entropy is severely constrained. This violates the OWASP ASVS v4 requirement of ≥ 64 bits of entropy (V3.2.2) and NIST SP 800-63B standards. By narrowing the LCG window (via server state leaks or general predictability) and leveraging the lack of API rate-limiting, an attacker can generate a localized pool of candidate MD5 hashes and execute a high-speed online brute-force attack to hijack active API sessions.Technical AnalysisCode PathNote: `init()` receives `$sessionName='api'` but invokes `$this->start()` without forwarding it, meaning the effective construction is strictly `md5(time() . uniqid('', true))`.Live EvidenceFive consecutive XML-RPC login tokens were collected from a live OpenMage 20.16.0 container, all generated within a single Unix second (`unix_sec=  1775817593`):The µsecond portion is directly observable by measuring request-to-response latency. The only variance preventing immediate prediction is the LCG float component, which is seeded deterministically.Steps to Reproduce (Online Brute-Force Scenario)Because validation requires live HTTP requests, this exploit relies on narrowing the entropy window and abusing the lack of API rate limits.Step 1 – Record Login TimestampAn attacker observes the precise moment a victim authenticates to `/api/xmlrpc/` (e.g., via network timing, exposed logs, or side-channel signals), capturing the exact Unix second.Step 2 – Generate Candidate PoolThe attacker reconstructs the MD5 format using the known timestamp, the estimated microsecond window, and bounds the LCG float based on known server PID ranges (or via a `/server-status` leak).Step 3 – API Brute-Force (Session Hijack)Because the `/api/xmlrpc/` endpoint does not enforce rate limiting on authenticated calls, the attacker blasts the candidate MD5 hashes against a privileged endpoint (e.g., magento.info) using a highly concurrent HTTP runner.A non-fault response (HTTP 200 containing data) confirms the session is successfully hijacked.ImpactTechnical ImpactSuccessful session prediction grants the attacker all capabilities of the authenticated API user. The XML-RPC API exposes endpoints for:Full product catalog read/write (`catalog_product.*`)Customer data read (`customer.list`, `customer.info`)Order manipulation (`sales_order.*`)
Inventory control (`cataloginventory_stock_item.*`)Business Impact**Data Exfiltration**: Read all customer PII, order history, and payment methods.**Order Fraud**: Create or cancel orders, change shipping addresses.**Supply Chain / Inventory**: Modify prices, inject malicious products, or zero out stock.Affected API ProtocolsThe same vulnerable `Session.php` generation logic is shared across all legacy API surfaces:XML-RPC: `/api/xmlrpc/`SOAP v1: `/api/soap/`SOAP v2: `/api/v2_soap/`REST (legacy): `/api/rest/`Recommended FixReplace the time-derived token with a cryptographically secure random value:`random_bytes()` is backed by the OS CSPRNG (`/dev/urandom` on Linux) and produces 256 bits of non-deterministic entropy, complying with OWASP ASVS v4 V3.2.2 and NIST SP 800-63B. Additionally, enforce rate limiting on API endpoints to prevent high-speed online brute-force attacks.I have also tried to test it against the demo site [demo.openmage.org](http://demo.openmage.org/), but appeared the SOAP API endpoints are disabled on the demo environmentI have also included the full poc I used instead of being attached because Gmail will eventually block it otherwise (shrunk):This is an AI-generated report validated by a human.
CVSS v4.0 score: 9.3