Security: gate marshal-based function deserialization behind enable_opaque_pickle#412
Open
koonnamchok wants to merge 1 commit into
Open
Security: gate marshal-based function deserialization behind enable_opaque_pickle#412koonnamchok wants to merge 1 commit into
koonnamchok wants to merge 1 commit into
Conversation
…paque_pickle Gate the marshal.loads() inline-code path in _function_from_json behind the existing _opaque_pickle_enabled flag, so enable_opaque_pickle(False) (the documented untrusted-JSON mitigation) also disables function-code deserialization. Reported and confirmed via Google OSS VRP (issue 523598901). No default-behaviour change; adds tests. See PR description.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Author
|
@googlebot I signed it! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
from_jsonreconstructs Python functions from inlinecodeviamarshal.loads()in_function_from_json. A payload{"_type": "function", "code": <base64 marshal>, ...}becomes a livetypes.FunctionType; calling it runs the embedded bytecode. Any consumer doingpg.from_json/pg.from_json_str/pg.loadon data it does not fully control is one call away from code execution.PyGlove already ships a documented mitigation,
enable_opaque_pickle(False)(its docstring targets "cloud services that process untrusted JSON"), but it only guarded the pickle_OpaqueObjectpath — the marshal/function path was unconditionally on, so an operator who followed the documented advice was still exposed.This was reported to and confirmed by the Google OSS VRP (issue 523598901).
Change
_function_from_json: the inline-code(marshal.loads) path is now gated by the same_opaque_pickle_enabledflag that guards pickle deserialization. When opaque pickle is disabled it raisesTypeErrorinstead of producing an executable function. The name-based path (_load_symbol) is unaffected.enable_opaque_pickledocstring updated to note it now also covers function-code deserialization.enable_opaque_pickle(False)rejects an inline-code function payload; default round-trip behaviour is preserved.No default-behaviour change (
enable_opaque_pickledefaults toTrue). Services that already adopted the documented mitigation are now protected against this path too.Verification
python -m unittest pyglove.core.utils.json_conversion_test— all 25 tests pass (2 new + existing, no regression). End-to-end PoC: by default a crafted function payload deserializes into a callable that executes on call; underenable_opaque_pickle(False)the same payload is rejected and nothing executes.