1. Bug Topic
Native::deserialize() executes PHP unserialize() on raw Encoding data before validating the resulting object type.
2. Release Version / Commit Hash / Affected Range
2.5.2 / 59782a2
3. Bug Type
Insecure deserialization / PHP object injection.
4. CWE
CWE-502: Deserialization of Untrusted Data.
5. Bug Summary
Rubix\ML\Serializers\Native::deserialize() accepts an Encoding object and passes it directly to unserialize(). Because validation happens after deserialization, a malicious object can run __wakeup() or later __destruct() side effects before RubixML throws an exception for non-Persistable objects.
6. Root Cause
The method relies on post-deserialization checks as if they were preconditions. They are too late to prevent object instantiation and lifecycle method execution. Encoding::__toString() returns raw caller-controlled data.
7. Attack Preconditions
A consuming application loads model data or serialized Native payloads from an untrusted or attacker-writable source and uses the Native serializer. The practical severity depends on host application gadget availability.
8. Impact Analysis
Potential PHP object injection. Depending on gadget classes loaded in the application, impact can range from local side effects to code execution. Even without a known gadget chain, untrusted Native payloads should not be deserialized with unrestricted PHP unserialize().
9. Affected Code
src/Serializers/Native.php:47-64
src/Encoding.php:74-77
10. PoC
https://github.com/fa1c4/security-advisories/tree/main/RubixML
docker build -t poc-rubixml-native-deserialization .
docker run --rm poc-rubixml-native-deserialization
1. Bug Topic
Native::deserialize()executes PHPunserialize()on rawEncodingdata before validating the resulting object type.2. Release Version / Commit Hash / Affected Range
2.5.2 / 59782a2
3. Bug Type
Insecure deserialization / PHP object injection.
4. CWE
CWE-502: Deserialization of Untrusted Data.
5. Bug Summary
Rubix\ML\Serializers\Native::deserialize()accepts anEncodingobject and passes it directly tounserialize(). Because validation happens after deserialization, a malicious object can run__wakeup()or later__destruct()side effects before RubixML throws an exception for non-Persistableobjects.6. Root Cause
The method relies on post-deserialization checks as if they were preconditions. They are too late to prevent object instantiation and lifecycle method execution.
Encoding::__toString()returns raw caller-controlled data.7. Attack Preconditions
A consuming application loads model data or serialized Native payloads from an untrusted or attacker-writable source and uses the Native serializer. The practical severity depends on host application gadget availability.
8. Impact Analysis
Potential PHP object injection. Depending on gadget classes loaded in the application, impact can range from local side effects to code execution. Even without a known gadget chain, untrusted Native payloads should not be deserialized with unrestricted PHP
unserialize().9. Affected Code
src/Serializers/Native.php:47-64src/Encoding.php:74-7710. PoC
https://github.com/fa1c4/security-advisories/tree/main/RubixMLdocker build -t poc-rubixml-native-deserialization . docker run --rm poc-rubixml-native-deserialization