Skip to content

Commit

Permalink
Serde: limit decode code execution (#3175)
Browse files Browse the repository at this point in the history
*Issue #, if available:*

*Description of changes:*


By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.


**Please tag this pr with at least one of these labels to make our
release process faster:** BREAKING, new feature, bug fix, other change,
dev setup
  • Loading branch information
lostella authored May 24, 2024
1 parent 38b0c64 commit a132eab
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/gluonts/core/serde/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ def encode_partial(v: partial) -> Any:
}


decode_disallow = [
eval,
exec,
compile,
open,
input,
]


def decode(r: Any) -> Any:
"""
Decodes a value from an intermediate representation `r`.
Expand All @@ -312,7 +321,10 @@ def decode(r: Any) -> Any:
kind = r["__kind__"]
cls = cast(Any, locate(r["class"]))

assert cls is not None, f"Can not locate {r['class']}."
if cls is None:
raise ValueError(f"Cannot locate {r['class']}.")
if cls in decode_disallow:
raise ValueError(f"{r['class']} cannot be run.")

if kind == Kind.Type:
return cls
Expand Down
23 changes: 23 additions & 0 deletions test/core/test_serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,26 @@ def test_serde_method():
def test_np_str_dtype():
a = np.array(["foo"])
serde.decode(serde.encode(a.dtype)) == a.dtype


@pytest.mark.parametrize(
"obj",
[
{"__kind__": 42, "class": cls_str}
for cls_str in [
"builtins.eval",
"builtins.exec",
"builtins.compile",
"builtins.open",
"builtins.input",
"eval",
"exec",
"compile",
"open",
"input",
]
],
)
def test_decode_disallow(obj):
with pytest.raises(ValueError):
serde.decode(obj)

0 comments on commit a132eab

Please sign in to comment.