Skip to content

Stringy::isSerialized() unsafe object deserialization side effect #215

Description

@fa1c4

1. Bug Topic

Stringy::isSerialized() performs native PHP deserialization and can execute magic methods while only checking whether a string is serialized.

2. Release Version / Commit Hash / Affected Range

0b76c56

3. Bug Type

Unsafe deserialization in a validator-like public API.

4. CWE

CWE-502: Deserialization of Untrusted Data.

5. Bug Summary

isSerialized() is documented as a boolean checker. It currently calls PHP's native unserialize() on the string value. If an application calls this method on untrusted data, the check can instantiate attacker-selected classes and invoke magic methods such as __wakeup().

6. Root Cause

PHP unserialize() is used as a format detector. This is unsafe because PHP deserialization has side effects. The code does not use allowed_classes => false and does not implement a parser-only serialized-string check.

7. Attack Preconditions

  • A consuming application accepts attacker-controlled input.
  • The application wraps that input in Stringy and calls isSerialized().
  • A class with a relevant magic method is autoloadable in the application environment.

8. Impact Analysis

The impact depends on available classes/gadget chains in the consuming application. The primitive is arbitrary object instantiation plus magic-method execution during a boolean check. With a suitable gadget chain, this can become application-level code execution or other side effects. Even without a gadget chain, the behavior violates the expected side-effect-free semantics of a predicate method.

9. Affected Code

File: src/Stringy.php

public function isSerialized()
{
    return $this->str === 'b:0;' || @unserialize($this->str) !== false;
}

10. PoC

https://github.com/fa1c4/security-advisories/tree/main/Stringy

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions