Skip to content

Insecure deserialization via pickle.loads() in json_conversion.py enables Command Injection/RCE if opaque JSON input is tampered #403

@JoshuaProvoste

Description

@JoshuaProvoste

The file json_conversion.py deserializes Base64-encoded pickle data using pickle.loads() without any integrity, provenance, or type allowlist validation.

If an attacker can control or tamper with the JSON input that flows through this deserialization path (for example via configuration files, artifacts, external inputs, or CI/CD pipelines), this results in arbitrary code execution during deserialization.

This behavior is triggered automatically when opaque objects (_OpaqueObject) are decoded through json_conversion.from_json().

The vulnerability originates from unconditional deserialization using pickle.loads(base64.decodebytes(...)) inside the decode() method of _OpaqueObject.

Full technical analysis, PoC generators, realistic CI/CD reproductions, and execution traces are documented here:

In environments where PyGlove is used to process JSON inputs automatically (CI/CD workflows, configuration pipelines, research experiments, or cloud-based systems), a poisoned opaque JSON object could lead to compromise of build runners, credentials, artifacts, or downstream consumers, effectively becoming a software supply-chain attack vector.

Happy to provide additional context if needed. Thank you for maintaining PyGlove.

— Joshua Provoste

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions