From bf559b19d811501a823291cfc4e5dd77d1fb4ca0 Mon Sep 17 00:00:00 2001 From: Stefan Krawczyk Date: Sun, 6 Sep 2026 21:51:03 -0700 Subject: [PATCH] Document pickle loader trust requirements --- SECURITY.md | 10 ++++++++++ docs/reference/io/available-data-adapters.rst | 6 ++++++ hamilton/io/default_data_loaders.py | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 9f6a459da..c6842fcbf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -29,6 +29,16 @@ We currently only support the latest version of Apache Hamilton that's been rele | ------- | ------------------ | | Latest | :white_check_mark: | +## Security Model + +Apache Hamilton executes user-authored Python functions in the host process. Dataflows, extensions, +and adapters therefore run with the same privileges as the Python process and must come from trusted +sources. + +Hamilton also provides an explicit loader for Python pickle files. Pickle deserialization can execute +arbitrary code, so `@load_from.pickle` and `PickleLoader` must only be used with files from trusted +sources. When data crosses a trust boundary, use a non-executable interchange format such as JSON, +Parquet, or Arrow instead. This is a project of the [Apache Software Foundation](https://apache.org) and follows the ASF [vulnerability handling process](https://apache.org/security/#vulnerability-handling). diff --git a/docs/reference/io/available-data-adapters.rst b/docs/reference/io/available-data-adapters.rst index a10b40bec..df064a2f9 100644 --- a/docs/reference/io/available-data-adapters.rst +++ b/docs/reference/io/available-data-adapters.rst @@ -17,6 +17,12 @@ to figure out which is the best for your case (the object you want to load from Finally, look up the adapter params to see what parameters you can pass to the data adapters. The optional params come with their default value specified. +.. warning:: + + Python pickle deserialization can execute arbitrary code. Only use the ``pickle`` data loader + with files from sources you trust. When data crosses a trust boundary, prefer a non-executable + interchange format such as JSON, Parquet, or Arrow. + If you want more information, click on the `module`, it will send you to the code that implements it to see how the parameters are used. diff --git a/hamilton/io/default_data_loaders.py b/hamilton/io/default_data_loaders.py index 1810e1fc8..913e65eb3 100644 --- a/hamilton/io/default_data_loaders.py +++ b/hamilton/io/default_data_loaders.py @@ -126,6 +126,13 @@ def save_data(self, data: bytes | io.BytesIO) -> dict[str, Any]: @dataclasses.dataclass class PickleLoader(DataLoader): + """Loads Python pickle files. + + Warning: pickle deserialization can execute arbitrary code. Only load pickle files from + sources you trust. Use a non-executable format such as JSON, Parquet, or Arrow when data + crosses a trust boundary. + """ + path: str @classmethod