modelaudit-picklescan 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. modelaudit_picklescan-0.1.2/CHANGELOG.md +94 -0
  2. modelaudit_picklescan-0.1.2/Cargo.lock +133 -0
  3. modelaudit_picklescan-0.1.2/Cargo.toml +23 -0
  4. modelaudit_picklescan-0.1.2/PKG-INFO +106 -0
  5. modelaudit_picklescan-0.1.2/README.md +79 -0
  6. modelaudit_picklescan-0.1.2/pyproject.toml +103 -0
  7. modelaudit_picklescan-0.1.2/rust/README.md +11 -0
  8. modelaudit_picklescan-0.1.2/rust/src/expansion.rs +309 -0
  9. modelaudit_picklescan-0.1.2/rust/src/lib.rs +21 -0
  10. modelaudit_picklescan-0.1.2/rust/src/nested.rs +1223 -0
  11. modelaudit_picklescan-0.1.2/rust/src/nested_surface.rs +143 -0
  12. modelaudit_picklescan-0.1.2/rust/src/opcode.rs +849 -0
  13. modelaudit_picklescan-0.1.2/rust/src/options.rs +100 -0
  14. modelaudit_picklescan-0.1.2/rust/src/policy.rs +276 -0
  15. modelaudit_picklescan-0.1.2/rust/src/post_budget.rs +616 -0
  16. modelaudit_picklescan-0.1.2/rust/src/pybridge.rs +34 -0
  17. modelaudit_picklescan-0.1.2/rust/src/report.rs +286 -0
  18. modelaudit_picklescan-0.1.2/rust/src/stack.rs +236 -0
  19. modelaudit_picklescan-0.1.2/rust/src/state.rs +4002 -0
  20. modelaudit_picklescan-0.1.2/rust/src/strings.rs +896 -0
  21. modelaudit_picklescan-0.1.2/rust/src/strings_policy.rs +79 -0
  22. modelaudit_picklescan-0.1.2/src/modelaudit_picklescan/__init__.py +21 -0
  23. modelaudit_picklescan-0.1.2/src/modelaudit_picklescan/api.py +1052 -0
  24. modelaudit_picklescan-0.1.2/src/modelaudit_picklescan/options.py +102 -0
  25. modelaudit_picklescan-0.1.2/src/modelaudit_picklescan/py.typed +1 -0
  26. modelaudit_picklescan-0.1.2/src/modelaudit_picklescan/report.py +202 -0
  27. modelaudit_picklescan-0.1.2/tests/conftest.py +8 -0
  28. modelaudit_picklescan-0.1.2/tests/parity_corpus.py +192 -0
  29. modelaudit_picklescan-0.1.2/tests/test_adversarial_pickle_oracle.py +302 -0
  30. modelaudit_picklescan-0.1.2/tests/test_api.py +2729 -0
  31. modelaudit_picklescan-0.1.2/tests/test_import_boundary.py +36 -0
  32. modelaudit_picklescan-0.1.2/tests/test_native_interface.py +48 -0
  33. modelaudit_picklescan-0.1.2/tests/test_options.py +55 -0
  34. modelaudit_picklescan-0.1.2/tests/test_report.py +167 -0
  35. modelaudit_picklescan-0.1.2/tests/test_rust_engine.py +367 -0
  36. modelaudit_picklescan-0.1.2/uv.lock +8 -0
@@ -0,0 +1,94 @@
1
+ # Changelog
2
+
3
+ All notable changes to `modelaudit-picklescan` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.2](https://github.com/promptfoo/modelaudit/releases/tag/modelaudit-picklescan-v0.1.2) (2026-04-17)
9
+
10
+ ### Bug Fixes
11
+
12
+ - repair picklescan release wheel jobs ([#1051](https://github.com/promptfoo/modelaudit/issues/1051)) ([6c23190](https://github.com/promptfoo/modelaudit/commit/6c23190f9b23686d33d5da0a8b5522a59490084e))
13
+
14
+ ## [0.1.1](https://github.com/promptfoo/modelaudit/releases/tag/modelaudit-picklescan-v0.1.1) (2026-04-17)
15
+
16
+ ### Features
17
+
18
+ - extract standalone pickle scanner package with parity harness ([#832](https://github.com/promptfoo/modelaudit/issues/832)) ([e2986cd](https://github.com/promptfoo/modelaudit/commit/e2986cddaa592306cc10541865f011b3dc99a0ba))
19
+
20
+ ### Bug Fixes
21
+
22
+ - address code quality findings ([#1038](https://github.com/promptfoo/modelaudit/issues/1038)) ([7af03cf](https://github.com/promptfoo/modelaudit/commit/7af03cf42f33f1b255eb9f9cbcaac6caccd48bc1))
23
+ - bound standalone pickle stream reads ([4d0cb84](https://github.com/promptfoo/modelaudit/commit/4d0cb84af010b4ed332ebbf17fc8bd0769fa8b6e))
24
+ - **deps:** update rust crate pyo3 to 0.28.0 ([#1006](https://github.com/promptfoo/modelaudit/issues/1006)) ([fe93b47](https://github.com/promptfoo/modelaudit/commit/fe93b47c839588b3f33cfd21f4380306ec418f2a))
25
+ - detect hidden pytorch zip pickles ([#1043](https://github.com/promptfoo/modelaudit/issues/1043)) ([19b6ebe](https://github.com/promptfoo/modelaudit/commit/19b6ebe505d2ba90f81d6284d07e111f77cbf0b5))
26
+ - flag pickle persistent ids ([#938](https://github.com/promptfoo/modelaudit/issues/938)) ([2cfba40](https://github.com/promptfoo/modelaudit/commit/2cfba403e21d53f46ba7089b655cebc564dcddaf))
27
+ - harden pickle nested bypass detection ([#1027](https://github.com/promptfoo/modelaudit/issues/1027)) ([c3a3b9d](https://github.com/promptfoo/modelaudit/commit/c3a3b9d1e4ffbd854e6003afbf6ebef1e708a619))
28
+ - harden standalone pickle scanner ([#901](https://github.com/promptfoo/modelaudit/issues/901)) ([31f7dd3](https://github.com/promptfoo/modelaudit/commit/31f7dd38c6bd77631ccdca90438312c4db2ac857))
29
+ - narrow suspicious dunder string detection ([#947](https://github.com/promptfoo/modelaudit/issues/947)) ([e866760](https://github.com/promptfoo/modelaudit/commit/e8667609d293d4391205ce4e8884fa3559030604))
30
+ - preserve picklescan stack state ([#910](https://github.com/promptfoo/modelaudit/issues/910)) ([fabac5c](https://github.com/promptfoo/modelaudit/commit/fabac5c9ead49c2ed5f8357dfa53ccdcce946527))
31
+
32
+ ### Documentation
33
+
34
+ - align markdown with current repo state ([#1035](https://github.com/promptfoo/modelaudit/issues/1035)) ([690bc52](https://github.com/promptfoo/modelaudit/commit/690bc5274198eb3428db9779ada0bdc2d40702ee))
35
+
36
+ ## [Unreleased]
37
+
38
+ ### Added
39
+
40
+ - Introduce the Rust-native pickle scanning engine and standalone Python API package.
41
+ - Add `scan_bytes`, `scan_stream`, and `scan_file` entrypoints with typed immutable
42
+ reports for findings, notices, errors, coverage, verdict, and scan status.
43
+ - Add direct PyTorch ZIP container handling for `data.pkl` and other pickle
44
+ members, including per-member source locations and combined archive reports.
45
+ - Add detection coverage for dangerous pickle globals and executed calls,
46
+ malformed `STACK_GLOBAL` operands, copyreg extension references, persistent
47
+ IDs, `__main__` call escalation, `__dict__` import-only references, structural
48
+ tamper, protocol-5 external-buffer opcodes, and memo/`DUP` expansion patterns.
49
+ - Add nested-pickle detection for raw bytes plus base64, hex, escaped-hex, and
50
+ comment-wrapped encoded payloads, with recursive scans and bounded deep-scan
51
+ limits.
52
+ - Add suspicious string-literal matching for execution helpers, loader helpers,
53
+ `getattr` variants, `os.system`/`subprocess`/`runpy`/`webbrowser` patterns,
54
+ encoded code strings, and pickle loader references.
55
+ - Improve detection so dangerous globals and expansion patterns remain
56
+ reportable even when opcode-budget limits are reached.
57
+ - Add resource controls for timeout, opcode budget, post-budget byte scans,
58
+ known-size and unknown-size stream reads, long string literal probing, nested
59
+ pickle byte budgets, nested depth, and import-reference metadata volume.
60
+ - Add Python package tests, Rust unit tests, parity-corpus tests, wheel smoke
61
+ checks, Ruff, mypy, cargo fmt/check/clippy/test, MSRV check, and manylinux
62
+ release-wheel gates.
63
+ - Probe binary pickle operands for nested pickle streams while intentionally
64
+ leaving arbitrary non-pickle text extraction from BINBYTES/tensor blobs to the
65
+ root ModelAudit raw detector layer.
66
+
67
+ ### Changed
68
+
69
+ - Use the Rust scanner as the only runtime engine; runtime engine selection and
70
+ Python-engine fallback behavior are not part of the public API.
71
+ - Release the Python GIL during native scans and avoid hot-path byte-literal
72
+ cloning by retaining borrowed payload spans for variable-length operands.
73
+ - Stream declared-size inputs in bounded chunks, normalize negative sizes as
74
+ unknown-size streams, cap both known-size and unbounded streams, and scan
75
+ partial bytes on declared-size short reads before returning an operational
76
+ error.
77
+ - Preserve standalone rule details while exposing ModelAudit-compatible rule
78
+ mappings for the root package, including dedicated nested-pickle, encoding,
79
+ persistent-ID, extension, structural-tamper, and expansion findings.
80
+
81
+ ### Fixed
82
+
83
+ - Detect policy-backed dangerous globals in post-budget tails instead of relying
84
+ on a small hardcoded byte-needle table.
85
+ - Detect nested payloads that use PERSID/BINPERSID semantics, proto-0 payloads,
86
+ uppercase escaped-hex prefixes, multiline/comment-wrapped encodings, and long
87
+ literals with suspicious content outside prefix/suffix windows.
88
+ - Preserve stack state on operand underflow.
89
+ - Avoid wrapping MARK sentinels.
90
+ - Preserve `GLOBAL`/`INST` module/name operands without string roundtrips.
91
+ - Keep follow-on pickle streams at sibling depth.
92
+ - Cap import-reference metadata with an explicit notice, summarize repeated
93
+ persistent IDs, coalesce protocol-5 buffer notices, and surface structural
94
+ tamper severity without adapter downgrades.
@@ -0,0 +1,133 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "heck"
7
+ version = "0.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
10
+
11
+ [[package]]
12
+ name = "libc"
13
+ version = "0.2.184"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
16
+
17
+ [[package]]
18
+ name = "modelaudit-picklescan-rust"
19
+ version = "0.1.2"
20
+ dependencies = [
21
+ "pyo3",
22
+ ]
23
+
24
+ [[package]]
25
+ name = "once_cell"
26
+ version = "1.21.4"
27
+ source = "registry+https://github.com/rust-lang/crates.io-index"
28
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
29
+
30
+ [[package]]
31
+ name = "portable-atomic"
32
+ version = "1.13.1"
33
+ source = "registry+https://github.com/rust-lang/crates.io-index"
34
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
35
+
36
+ [[package]]
37
+ name = "proc-macro2"
38
+ version = "1.0.106"
39
+ source = "registry+https://github.com/rust-lang/crates.io-index"
40
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
41
+ dependencies = [
42
+ "unicode-ident",
43
+ ]
44
+
45
+ [[package]]
46
+ name = "pyo3"
47
+ version = "0.28.3"
48
+ source = "registry+https://github.com/rust-lang/crates.io-index"
49
+ checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12"
50
+ dependencies = [
51
+ "libc",
52
+ "once_cell",
53
+ "portable-atomic",
54
+ "pyo3-build-config",
55
+ "pyo3-ffi",
56
+ "pyo3-macros",
57
+ ]
58
+
59
+ [[package]]
60
+ name = "pyo3-build-config"
61
+ version = "0.28.3"
62
+ source = "registry+https://github.com/rust-lang/crates.io-index"
63
+ checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e"
64
+ dependencies = [
65
+ "target-lexicon",
66
+ ]
67
+
68
+ [[package]]
69
+ name = "pyo3-ffi"
70
+ version = "0.28.3"
71
+ source = "registry+https://github.com/rust-lang/crates.io-index"
72
+ checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e"
73
+ dependencies = [
74
+ "libc",
75
+ "pyo3-build-config",
76
+ ]
77
+
78
+ [[package]]
79
+ name = "pyo3-macros"
80
+ version = "0.28.3"
81
+ source = "registry+https://github.com/rust-lang/crates.io-index"
82
+ checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813"
83
+ dependencies = [
84
+ "proc-macro2",
85
+ "pyo3-macros-backend",
86
+ "quote",
87
+ "syn",
88
+ ]
89
+
90
+ [[package]]
91
+ name = "pyo3-macros-backend"
92
+ version = "0.28.3"
93
+ source = "registry+https://github.com/rust-lang/crates.io-index"
94
+ checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb"
95
+ dependencies = [
96
+ "heck",
97
+ "proc-macro2",
98
+ "pyo3-build-config",
99
+ "quote",
100
+ "syn",
101
+ ]
102
+
103
+ [[package]]
104
+ name = "quote"
105
+ version = "1.0.45"
106
+ source = "registry+https://github.com/rust-lang/crates.io-index"
107
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
108
+ dependencies = [
109
+ "proc-macro2",
110
+ ]
111
+
112
+ [[package]]
113
+ name = "syn"
114
+ version = "2.0.117"
115
+ source = "registry+https://github.com/rust-lang/crates.io-index"
116
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
117
+ dependencies = [
118
+ "proc-macro2",
119
+ "quote",
120
+ "unicode-ident",
121
+ ]
122
+
123
+ [[package]]
124
+ name = "target-lexicon"
125
+ version = "0.13.5"
126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
127
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
128
+
129
+ [[package]]
130
+ name = "unicode-ident"
131
+ version = "1.0.24"
132
+ source = "registry+https://github.com/rust-lang/crates.io-index"
133
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
@@ -0,0 +1,23 @@
1
+ [package]
2
+ name = "modelaudit-picklescan-rust"
3
+ version = "0.1.2" # x-release-please-version
4
+ edition = "2021"
5
+ rust-version = "1.83"
6
+ description = "Native pickle security scanner engine for modelaudit-picklescan"
7
+ license = "MIT"
8
+ repository = "https://github.com/promptfoo/modelaudit"
9
+ publish = false
10
+ readme = "README.md"
11
+
12
+ [lib]
13
+ name = "modelaudit_picklescan_rust"
14
+ path = "rust/src/lib.rs"
15
+ crate-type = ["cdylib", "rlib"]
16
+
17
+ [features]
18
+ default = []
19
+ extension-module = ["pyo3/extension-module"]
20
+ abi3 = ["pyo3/abi3-py310"]
21
+
22
+ [dependencies]
23
+ pyo3 = { version = "0.28.0" }
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.4
2
+ Name: modelaudit-picklescan
3
+ Version: 0.1.2
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Topic :: Security
8
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Summary: Standalone pickle security scanner extracted from ModelAudit
15
+ Keywords: pickle,security,model-scanning,ml
16
+ Author-email: Ian Webster <ian@promptfoo.dev>, Michael D'Angelo <michael@promptfoo.dev>, Yash Chhabria <yash@promptfoo.dev>
17
+ License: MIT
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
20
+ Project-URL: Changelog, https://github.com/promptfoo/modelaudit/blob/main/packages/modelaudit-picklescan/CHANGELOG.md
21
+ Project-URL: Documentation, https://github.com/promptfoo/modelaudit/tree/main/packages/modelaudit-picklescan
22
+ Project-URL: Homepage, https://github.com/promptfoo/modelaudit
23
+ Project-URL: Issues, https://github.com/promptfoo/modelaudit/issues
24
+ Project-URL: Repository, https://github.com/promptfoo/modelaudit
25
+ Project-URL: Security, https://github.com/promptfoo/modelaudit/security/policy
26
+
27
+ # modelaudit-picklescan
28
+
29
+ Standalone pickle security scanner package used by ModelAudit's pickle scanners.
30
+
31
+ This package is intentionally small: it exposes pickle byte/stream analysis,
32
+ safety verdicts, typed findings, and direct scanning of pickle members inside
33
+ common PyTorch ZIP checkpoints without importing the broader ModelAudit scanner
34
+ framework.
35
+
36
+ ## Installation
37
+
38
+ The standalone `modelaudit-picklescan` wheel includes the Python API and the
39
+ native Rust scanner extension. The root `modelaudit` wheel depends on this
40
+ distribution so installed ModelAudit scans use the same native Rust scanner for
41
+ pickle payload analysis.
42
+
43
+ For local package work from a checkout, install the package directory directly:
44
+
45
+ ```bash
46
+ python -m pip install packages/modelaudit-picklescan
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ```python
52
+ from modelaudit_picklescan import ScanOptions, scan_bytes, scan_file
53
+
54
+ report = scan_file("model.pt") # raw pickle files and PyTorch ZIP checkpoints
55
+ if report.has_security_findings:
56
+ for finding in report.findings:
57
+ print(finding.rule_code, finding.severity.value, finding.message)
58
+
59
+ report = scan_bytes(
60
+ payload,
61
+ source="archive.pt:data.pkl",
62
+ options=ScanOptions(
63
+ timeout_s=30.0,
64
+ max_opcodes=1_000_000,
65
+ max_string_literal_scan_chars=8 * 1024 * 1024,
66
+ max_nested_pickle_bytes=2 * 1024 * 1024,
67
+ max_nested_depth=2,
68
+ ),
69
+ )
70
+ ```
71
+
72
+ ## Native Scanner
73
+
74
+ The wheel includes a native Rust scanner for pickle payload analysis.
75
+ Nested pickle payload analysis is capped by byte budget and depth; the default
76
+ depth is 2 so common double-wrapped encoded pickle payloads are inspected while
77
+ recursive or adversarial nesting stays bounded.
78
+ Release wheels are published for Linux x86_64, Linux aarch64, macOS arm64,
79
+ macOS x86_64, and Windows targets. Other platforms may install from the source
80
+ distribution and need a local Rust toolchain available during install.
81
+ Use Rust 1.83+ when building from source.
82
+
83
+ ## Report Contract
84
+
85
+ - `status`: scan completeness (`complete`, `inconclusive`, `error`)
86
+ - `verdict`: safety decision (`clean`, `suspicious`, `malicious`, `unknown`)
87
+ - `findings`: warning/critical security findings
88
+ - `notices`: informational coverage notes, including explicit partial-analysis
89
+ notices when literal or nested-pickle budgets are reached
90
+ - `errors`: operational failures
91
+
92
+ Notices are intended for explainability and audit trails. Aggregate dashboards
93
+ should treat `findings` at `warning` or `critical` severity as security alerts,
94
+ and group or count `notices` by code instead of presenting every INFO row as an
95
+ actionable issue.
96
+
97
+ Report mappings are read-only after construction. Use `to_dict()` when a mutable
98
+ plain-Python representation is needed.
99
+
100
+ ## Package Boundary
101
+
102
+ `modelaudit-picklescan` analyzes raw pickle payloads and PyTorch ZIP checkpoint
103
+ pickle members. For full model-file routing, archive context, CLI output,
104
+ SARIF/export integrations, and broader scanner coverage, use the root
105
+ `modelaudit` package.
106
+
@@ -0,0 +1,79 @@
1
+ # modelaudit-picklescan
2
+
3
+ Standalone pickle security scanner package used by ModelAudit's pickle scanners.
4
+
5
+ This package is intentionally small: it exposes pickle byte/stream analysis,
6
+ safety verdicts, typed findings, and direct scanning of pickle members inside
7
+ common PyTorch ZIP checkpoints without importing the broader ModelAudit scanner
8
+ framework.
9
+
10
+ ## Installation
11
+
12
+ The standalone `modelaudit-picklescan` wheel includes the Python API and the
13
+ native Rust scanner extension. The root `modelaudit` wheel depends on this
14
+ distribution so installed ModelAudit scans use the same native Rust scanner for
15
+ pickle payload analysis.
16
+
17
+ For local package work from a checkout, install the package directory directly:
18
+
19
+ ```bash
20
+ python -m pip install packages/modelaudit-picklescan
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```python
26
+ from modelaudit_picklescan import ScanOptions, scan_bytes, scan_file
27
+
28
+ report = scan_file("model.pt") # raw pickle files and PyTorch ZIP checkpoints
29
+ if report.has_security_findings:
30
+ for finding in report.findings:
31
+ print(finding.rule_code, finding.severity.value, finding.message)
32
+
33
+ report = scan_bytes(
34
+ payload,
35
+ source="archive.pt:data.pkl",
36
+ options=ScanOptions(
37
+ timeout_s=30.0,
38
+ max_opcodes=1_000_000,
39
+ max_string_literal_scan_chars=8 * 1024 * 1024,
40
+ max_nested_pickle_bytes=2 * 1024 * 1024,
41
+ max_nested_depth=2,
42
+ ),
43
+ )
44
+ ```
45
+
46
+ ## Native Scanner
47
+
48
+ The wheel includes a native Rust scanner for pickle payload analysis.
49
+ Nested pickle payload analysis is capped by byte budget and depth; the default
50
+ depth is 2 so common double-wrapped encoded pickle payloads are inspected while
51
+ recursive or adversarial nesting stays bounded.
52
+ Release wheels are published for Linux x86_64, Linux aarch64, macOS arm64,
53
+ macOS x86_64, and Windows targets. Other platforms may install from the source
54
+ distribution and need a local Rust toolchain available during install.
55
+ Use Rust 1.83+ when building from source.
56
+
57
+ ## Report Contract
58
+
59
+ - `status`: scan completeness (`complete`, `inconclusive`, `error`)
60
+ - `verdict`: safety decision (`clean`, `suspicious`, `malicious`, `unknown`)
61
+ - `findings`: warning/critical security findings
62
+ - `notices`: informational coverage notes, including explicit partial-analysis
63
+ notices when literal or nested-pickle budgets are reached
64
+ - `errors`: operational failures
65
+
66
+ Notices are intended for explainability and audit trails. Aggregate dashboards
67
+ should treat `findings` at `warning` or `critical` severity as security alerts,
68
+ and group or count `notices` by code instead of presenting every INFO row as an
69
+ actionable issue.
70
+
71
+ Report mappings are read-only after construction. Use `to_dict()` when a mutable
72
+ plain-Python representation is needed.
73
+
74
+ ## Package Boundary
75
+
76
+ `modelaudit-picklescan` analyzes raw pickle payloads and PyTorch ZIP checkpoint
77
+ pickle members. For full model-file routing, archive context, CLI output,
78
+ SARIF/export integrations, and broader scanner coverage, use the root
79
+ `modelaudit` package.
@@ -0,0 +1,103 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.9,<2"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "modelaudit-picklescan"
7
+ version = "0.1.2" # x-release-please-version
8
+ description = "Standalone pickle security scanner extracted from ModelAudit"
9
+ authors = [
10
+ { name = "Ian Webster", email = "ian@promptfoo.dev" },
11
+ { name = "Michael D'Angelo", email = "michael@promptfoo.dev" },
12
+ { name = "Yash Chhabria", email = "yash@promptfoo.dev" },
13
+ ]
14
+ license = { text = "MIT" }
15
+ readme = "README.md"
16
+ keywords = ["pickle", "security", "model-scanning", "ml"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Topic :: Security",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ ]
29
+ requires-python = ">=3.10"
30
+ dependencies = []
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/promptfoo/modelaudit"
34
+ Documentation = "https://github.com/promptfoo/modelaudit/tree/main/packages/modelaudit-picklescan"
35
+ Repository = "https://github.com/promptfoo/modelaudit"
36
+ Issues = "https://github.com/promptfoo/modelaudit/issues"
37
+ Changelog = "https://github.com/promptfoo/modelaudit/blob/main/packages/modelaudit-picklescan/CHANGELOG.md"
38
+ Security = "https://github.com/promptfoo/modelaudit/security/policy"
39
+
40
+ [tool.maturin]
41
+ python-source = "src"
42
+ module-name = "modelaudit_picklescan._rust"
43
+ features = ["extension-module", "abi3"]
44
+
45
+ [tool.ruff]
46
+ line-length = 120
47
+ target-version = "py310"
48
+
49
+ [tool.ruff.lint]
50
+ extend-select = [
51
+ "I",
52
+ "W",
53
+ "E",
54
+ "Q",
55
+ "COM",
56
+ "UP",
57
+ "B",
58
+ "C4",
59
+ "SIM",
60
+ "RUF",
61
+ ]
62
+ ignore = [
63
+ "COM812",
64
+ ]
65
+
66
+ [tool.ruff.lint.per-file-ignores]
67
+ "__init__.py" = ["F401"]
68
+ "tests/**/*.py" = ["S101", "F841"]
69
+
70
+ [tool.ruff.lint.flake8-quotes]
71
+ inline-quotes = "double"
72
+ multiline-quotes = "double"
73
+ docstring-quotes = "double"
74
+ avoid-escape = true
75
+
76
+ [tool.ruff.format]
77
+ quote-style = "double"
78
+
79
+ [tool.pytest.ini_options]
80
+ minversion = "7.0"
81
+ addopts = [
82
+ "-ra",
83
+ "--strict-markers",
84
+ "--strict-config",
85
+ "--disable-warnings",
86
+ "--tb=short",
87
+ ]
88
+ testpaths = ["tests"]
89
+
90
+ [tool.mypy]
91
+ python_version = "3.10"
92
+ warn_return_any = true
93
+ warn_unused_configs = true
94
+ warn_redundant_casts = true
95
+ warn_unreachable = true
96
+ no_implicit_optional = true
97
+ strict_equality = true
98
+ show_error_codes = true
99
+ show_column_numbers = true
100
+ pretty = true
101
+ check_untyped_defs = true
102
+ disallow_incomplete_defs = true
103
+ ignore_missing_imports = true
@@ -0,0 +1,11 @@
1
+ # modelaudit-picklescan Rust Engine
2
+
3
+ This directory contains the native scanner crate included in the
4
+ `modelaudit-picklescan` Python package.
5
+
6
+ For installation, Python API examples, supported report fields, and package
7
+ boundary details, see `../README.md`.
8
+
9
+ For contributor validation notes, see:
10
+
11
+ - `../../../docs/agents/picklescan-package-split.md`