Miggo Logo

CVE-2025-48951:
Auth0-PHP SDK Deserialization of Untrusted Data vulnerability

9.3

CVSS Score

Basic Information

EPSS Score
-
Published
6/4/2025
Updated
6/4/2025
KEV Status
No
Technology
TechnologyPHP

Technical Details

CVSS Vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Package NameEcosystemVulnerable VersionsFirst Patched Version
auth0/auth0-phpcomposer>= 8.0.0-BETA3, < 8.3.18.3.1

Vulnerability Intelligence
Miggo AIMiggo AI

Miggo AIRoot Cause Analysis

The vulnerability (CVE-2025-48951 / GHSA-v9m8-9xxp-q492) is a Deserialization of Untrusted Data (CWE-502) in the Auth0-PHP SDK, specifically within the CookieStore class. The root cause was the use of PHP's unserialize() function in the Auth0\SDK\Store\CookieStore::decrypt() method. This method was tasked with processing data read from cookies.

The Auth0\SDK\Store\CookieStore::getState() method is responsible for fetching raw cookie data from the $_COOKIE superglobal. It would concatenate relevant cookie parts and then pass this combined string to the decrypt() method.

Inside decrypt(), before the patch, this cookie-derived string was subjected to unserialize() at multiple points: once to parse an outer structure (if encrypted, this structure contained elements like an initialization vector, a tag, and the encrypted data itself) and again to deserialize the core data payload (either after decryption or directly if encryption was not used).

An attacker could craft a malicious cookie containing a specially serialized PHP object. When getState() read this cookie and passed its content to decrypt(), the unserialize() calls would then attempt to instantiate this malicious object. If a suitable PHP class (a "gadget") was available in the application's class path that could be misused upon deserialization (e.g., via magic methods like __wakeup() or __destruct()), this could lead to various impacts, including remote code execution, data exposure, or denial of service.

The patch addressed this by completely removing the usage of serialize() and unserialize(). Instead, json_encode() is now used for preparing data for cookie storage (in the encrypt method, which was also modified) and json_decode() (with true for associative arrays) is used in the decrypt() method for safely parsing the cookie data. Additionally, setrawcookie() is used instead of setcookie() to prevent unintended URL encoding/decoding issues with the cookie values. This ensures that only simple data structures are processed, mitigating the risk of object injection.

Vulnerable functions

Auth0\SDK\Store\CookieStore::decrypt
src/Store/CookieStore.php
This function was directly responsible for deserializing data originating from cookies. Prior to the patch, it used `unserialize()` in multiple places: to parse the structure of the encrypted cookie data (containing 'iv', 'tag', and 'data') and to deserialize the actual payload after decryption, or directly if encryption was off. Using `unserialize()` on untrusted input can lead to PHP object injection, allowing an attacker to instantiate arbitrary objects and potentially achieve remote code execution if a suitable gadget chain is available.
Auth0\SDK\Store\CookieStore::getState
src/Store/CookieStore.php
This function is responsible for retrieving raw data from cookies (`$_COOKIE`) and then passing this untrusted, potentially attacker-controlled data to the `decrypt()` method. As the `decrypt()` method contained the unsafe deserialization logic (use of `unserialize()`) before the patch, `getState()` acts as the function that processes and channels the malicious input into the vulnerable part of the code.

WAF Protection Rules

WAF Rule

**Ov*rvi*w** T** *ut** P*P S*K *ont*ins * vuln*r**ility *u* to ins**ur* **s*ri*liz*tion o* *ooki* **t*. I* *xploit**, sin** S*Ks pro**ss *ooki* *ont*nt wit*out prior *ut**nti**tion, * t*r**t **tor *oul* s*n* * sp**i*lly *r**t** *ooki* *ont*inin* m*li

Reasoning

T** vuln*r**ility (*V*-****-***** / **S*-v*m*-*xxp-q***) is * **s*ri*liz*tion o* Untrust** **t* (*W*-***) in t** *ut**-P*P S*K, sp**i*i**lly wit*in t** `*ooki*Stor*` *l*ss. T** root **us* w*s t** us* o* P*P's `uns*ri*liz*()` *un*tion in t** `*ut**\S*