diff --git a/src/wardline/scanner/rules/untrusted_to_deserialization.py b/src/wardline/scanner/rules/untrusted_to_deserialization.py index 63cc4e5b..cae39031 100644 --- a/src/wardline/scanner/rules/untrusted_to_deserialization.py +++ b/src/wardline/scanner/rules/untrusted_to_deserialization.py @@ -127,8 +127,10 @@ def _has_literal_true_kw(call: ast.Call, name: str) -> bool: "@trusted(level='ASSURED')\ndef f(p):\n blob = validate(read_raw(p))\n" " obj = pickle.loads(blob)\n return blob", # numpy.load without allow_pickle=True is safe by default (no object unpickling). + # We must not return its result directly to avoid a PY-WL-101 finding, as numpy.load + # is a serialization sink shedding validation provenance. "@external_boundary\ndef read_raw(p):\n return p\n" - "@trusted(level='ASSURED')\ndef f(p):\n return numpy.load(read_raw(p))", + "@trusted(level='ASSURED')\ndef f(p):\n numpy.load(read_raw(p))\n return 'safe'", ), ) diff --git a/src/wardline/scanner/taint/variable_level.py b/src/wardline/scanner/taint/variable_level.py index a51a6989..2ef43473 100644 --- a/src/wardline/scanner/taint/variable_level.py +++ b/src/wardline/scanner/taint/variable_level.py @@ -67,6 +67,12 @@ "tomllib.load", "tomli_w.dumps", "tomli_w.dump", + "dill.load", + "dill.loads", + "jsonpickle.decode", + "joblib.load", + "torch.load", + "numpy.load", } )