Mar 27, 2026·5 min read·1 visit
CVE-2026-33942 is a critical insecure deserialization flaw in Saloon PHP (<4.0.0). By injecting crafted serialized objects into token caches, attackers can trigger PHP gadget chains to achieve unauthenticated Remote Code Execution.
Saloon PHP library versions prior to 4.0.0 suffer from a critical insecure deserialization vulnerability. Unsafe handling of cached OAuth tokens in the AccessTokenAuthenticator class allows attackers to achieve Remote Code Execution (RCE) via PHP object injection.
Saloon is a PHP library used for building API integrations and SDKs. Versions of saloonphp/saloon prior to 4.0.0 contain a critical insecure deserialization vulnerability designated as CVE-2026-33942 (CWE-502). The flaw resides in the AccessTokenAuthenticator class, specifically in the mechanism used to restore OAuth token states from cache or storage.
The vulnerability yields a CVSS 3.1 score of 9.8, reflecting its maximum impact on confidentiality, integrity, and availability. Successful exploitation allows an attacker to achieve unauthenticated Remote Code Execution (RCE). This requires the attacker to manipulate the serialized cache or storage files that the application subsequently reads.
This vulnerability primarily affects PHP applications that rely heavily on Saloon for API management with token caching enabled. Environments where the storage mechanism lacks strict access controls or file integrity monitoring are particularly susceptible to exploitation.
The root cause of CVE-2026-33942 is the unsafe usage of PHP's native unserialize() function. The AccessTokenAuthenticator::unserialize() method accepts a string payload and passes it directly to unserialize(). The implementation explicitly sets the allowed_classes option to true, which is the default but highly dangerous behavior for untrusted data.
When unserialize() processes a crafted serialized string, it instantiates the encoded objects regardless of their original intent. During the instantiation or destruction phases, PHP automatically invokes magic methods such as __wakeup(), __destruct(), or __toString(). This mechanism forms the basis of PHP Object Injection.
The vulnerability itself provides the entry point, but achieving RCE requires a secondary component known as a gadget chain. Attackers leverage classes already present in the application's autoloader, including common dependencies like Monolog or Guzzle. By chaining these objects together, the attacker constructs a sequence of method calls that ultimately execute arbitrary operating system commands.
In Saloon v3.x, the AccessTokenAuthenticator class implemented custom serialization methods that wrapped PHP's native functionality without any input validation. The vulnerable code path explicitly allowed the deserialization of any class available in the autoloader.
// Pre-patch code (v3.x)
public function serialize(): string
{
return serialize($this);
}
public static function unserialize(string $string): static
{
// VULNERABLE: allowed_classes is set to true
return unserialize($string, ['allowed_classes' => true]);
}The maintainers addressed this flaw in commit d418356b6257a847f92a0bfa0c2d48bb379c731d by completely removing the serialize() and unserialize() methods. This architectural change eliminates the attack surface entirely.
// Post-patch code (v4.0.0)
// The serialize() and unserialize() methods have been completely removed.
// Developers must now implement custom persistence using safe formats like JSON.By stripping out the native serialization wrapping, developers are forced to manage token persistence manually. The recommended approach utilizes json_encode() and json_decode(), which process data strictly as standard objects or associative arrays and do not trigger PHP magic methods.
Exploitation proceeds in three distinct phases. First, the attacker must achieve injection. Since the vulnerability processes cached token states, the attacker must overwrite the cache file or inject a payload into the database field where the serialized token is stored. This often relies on a secondary file upload flaw or weak directory permissions.
Second, the attacker generates the serialized payload using tools like PHPGGC (PHP Generic Gadget Chains). They select a gadget chain compatible with the application's specific dependency tree. For example, if the application uses Monolog, the attacker might generate a Monolog/RCE1 payload designed to execute a specific bash command.
Finally, the application triggers the payload when it attempts to authenticate an API request. Saloon reads the compromised cache file and passes the contents to AccessTokenAuthenticator::unserialize(). The execution of the gadget chain results in arbitrary code execution under the context of the web server user.
The primary impact of CVE-2026-33942 is complete system compromise via Remote Code Execution. An attacker gaining code execution can read sensitive environment variables, extract database credentials, and pivot to internal networks. The CVSS score of 9.8 reflects the lack of user interaction required and the maximum impact on the environment.
Beyond deserialization, Saloon v3.x exhibited secondary attack surfaces addressed in the v4.0.0 release. Commit 1307b1d72cacdd2c9c20978cdf7a0b720b4bf3bb resolved Server-Side Request Forgery (SSRF) risks. The update modified URLHelper::join to reject absolute URLs in endpoints, preventing the leakage of API credentials to attacker-controlled hosts.
Furthermore, the version 4.0.0 update introduced path traversal prevention in Saloon\Helpers\Storage and strict alphanumeric validation for fixture names. These defense-in-depth measures mitigate the risk of attackers reading arbitrary files or escaping the intended cache directories via manipulated mock files.
The definitive remediation is upgrading saloonphp/saloon to version 4.0.0 or later. This release fundamentally alters how authenticators are handled by removing the vulnerable serialization methods entirely. Users must consult the Saloon v3 to v4 Upgrade Guide to adjust their persistence layers accordingly.
For developers migrating to v4.0.0, authenticators must now be persisted using safe formats. The recommended approach is applying json_encode() and json_decode() to store token arrays. This ensures the data is strictly parsed as an associative array or standard object, completely bypassing PHP's object instantiation lifecycle.
If immediate upgrading is impossible, administrators must implement strict access controls on the storage mechanisms used for caching tokens. Ensure cache directories have restrictive permissions (e.g., 0600 or 0700) and validate that database inputs cannot be modified by unprivileged users. Implementing file integrity monitoring on cache directories will help detect unauthorized modifications.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
saloon SaloonPHP | < 4.0.0 | 4.0.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-502 |
| Attack Vector | Network |
| CVSS v3.1 Score | 9.8 |
| Impact | Remote Code Execution (RCE) |
| EPSS Score | 0.00325 |
| Exploit Status | Proof of Concept via Gadget Chains |
Deserialization of untrusted data allowing attacker-controlled object instantiation.