From ca927a08e144a789441545fc31911fee70e239d7 Mon Sep 17 00:00:00 2001 From: Lucas Bourtoule Date: Fri, 13 Oct 2023 16:55:54 +0200 Subject: [PATCH] msgpack-numpy rule --- python/msgpack-numpy.py | 21 ++++++++++++++++++++ python/msgpack-numpy.yaml | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 python/msgpack-numpy.py create mode 100644 python/msgpack-numpy.yaml diff --git a/python/msgpack-numpy.py b/python/msgpack-numpy.py new file mode 100644 index 0000000..b7b3923 --- /dev/null +++ b/python/msgpack-numpy.py @@ -0,0 +1,21 @@ +import msgpack +import msgpack_numpy as m +import numpy as np + +x = np.random.rand(5) +# ruleid: msgpack-numpy +x_enc = msgpack.packb(x, default=m.encode) +# ruleid: msgpack-numpy +x_rec = msgpack.unpackb(x_enc, object_hook=m.decode) + +# ok: msgpack-numpy +x_enc2 = msgpack.packb(x) +# ok: msgpack-numpy +x_rec2 = msgpack.unpackb(x_enc2) + +m.patch() + +# ruleid: msgpack-numpy +x_enc3 = msgpack.packb(x) +# ruleid: msgpack-numpy +x_rec3 = msgpack.unpackb(x_enc2) diff --git a/python/msgpack-numpy.yaml b/python/msgpack-numpy.yaml new file mode 100644 index 0000000..91b9ba1 --- /dev/null +++ b/python/msgpack-numpy.yaml @@ -0,0 +1,40 @@ +rules: +- id: msgpack-numpy + message: >- + Found usage of msgpack-numpy unpacking, which relies on pickle to deserialize numpy arrays containing objects. + Functions reliant on pickle can result in arbitrary code execution. + Consider switching to a safer serialization method. + languages: [python] + severity: ERROR + metadata: + category: security + cwe: "CWE-502: Deserialization of Untrusted Data" + subcategory: [vuln] + confidence: MEDIUM + likelihood: MEDIUM + impact: HIGH + technology: [numpy] + description: "Potential arbitrary code execution from functions reliant on pickling" + references: + - https://blog.trailofbits.com/2021/03/15/never-a-dill-moment-exploiting-machine-learning-pickle-files/ + + pattern-either: + - patterns: + - pattern: msgpack.$FN(...) + - metavariable-regex: + metavariable: $FN + regex: (loads?|dumps?|packb?|unpackb?) + - pattern-inside: | + msgpack_numpy.patch() + ... + - pattern-either: + - patterns: + - pattern: msgpack.$FN(..., object_hook=msgpack_numpy.decode, ...) + - metavariable-regex: + metavariable: $FN + regex: unpackb? + - patterns: + - pattern: msgpack.$FN(..., default=msgpack_numpy.encode, ...) + - metavariable-regex: + metavariable: $FN + regex: packb?