Changelog
August 1, 2026 · View on GitHub
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
Bug Fixes
- Avoid network false positives for bounded README examples that download sample images over HTTPS from Hugging Face.
- Prevent Windows cache identity probes from creating locked temporary files inside scanned directories.
- Preserve locked Windows cache probes reached through directory aliases while clearing stale scan results.
- Place cross-volume Windows cache identity probes near the volume root instead of the nearest ancestor of the scanned path, so a probe can no longer appear inside a directory tree that a concurrent scan is walking.
0.2.52 (2026-07-22)
Bug Fixes
- cache: retry transient identity barrier churn (#1778) (72c8d22)
- deps: update GitPython to 3.1.51 (#1774) (e9b331b)
- deps: update pyasn1 to 0.6.4 (#1772) (df81361)
- deps: update setuptools to 83.0.0 (#1773) (8c805ff)
- harden GGUF/ZIP polyglot detection (#1775) (665ed3a)
- harden LZ4-compressed Joblib inspection (#1776) (fac0ede); thanks to @PowerliftLog for the report
- keep root-only release branches componentless (#1766) (9b8c2ce)
- picklescan: recognize uv bytes-encoded package overlays (#1777) (e9910fa)
- recover root release provenance safely (#1770) (1e0dcb6)
- resolve CodeQL quality and logging findings (#1769) (573bbd8)
0.2.51 (2026-07-20)
Bug Fixes
0.2.50 (2026-07-20)
Security
- validate Windows MLflow staging hardlinks with native file identities so aliases outside the staging tree fail closed
- treat protocol-relative report sources as remote identifiers before any Windows UNC filesystem probe
- reject premature pickle
STOPopcodes inside Joblib NumPy wrapper streams and fail closed when wrapper validation cannot complete
Bug Fixes
- cache: reuse stat without breaking public overrides (#1732) (39cd664)
- cli: handle startup interrupts gracefully (#1723) (839c7cf)
- deep-merge partial auth config updates (#1721) (8f33995)
- deps: update PyTorch to 2.13.0 for CVE-2025-3000; PyTorch-containing extras now require macOS 14 or newer on Apple Silicon and standard (GIL-enabled) CPython 3.13 or Python 3.10-3.12; CPython 3.13t is unsupported, while core-only remains available on macOS 11-13
- deps: require Click 8.3.3 or newer to address PYSEC-2026-2132
- deps: require
modelaudit-picklescan>=0.1.9so root upgrades receive the released scanner fixes - deps: update NumPy to 2.5 on Python 3.12+ while retaining NumPy 2.4 on Python 3.11, matching NumPy's supported Python versions (#1706) (eeba9b8)
- hashing: adapt reads near scan deadlines (#1734) (f23e1c0)
- picklescan: preserve POSIX ctime checks (#1719) (cbde525)
- picklescan: resolve reviewed runtime
hasattrguards without losing call-graph sinks - picklescan: restore standalone CI (#1742) (88632fe)
- restore cross-platform nightly CI safety (#1704) (9df81da)
0.2.49 (2026-06-25)
Bug Fixes
0.2.48 (2026-06-24)
Bug Fixes
- accept gzip-framed NeMo archives (#1634) (7be6b46)
- audit dependencies for source changes (#1535) (bf1e109)
- avoid exact-budget cloud pickle false positives (#1595) (350baa0)
- bind direct shard cache to siblings (#1543) (45bf167)
- bound executorch zip scanning (#1546) (ff9e1ae)
- bound jinja scalar range render probes (#1553) (c00542e)
- bound joblib decompression output (#1522) (98f41b1)
- bound keras zip config traversal (#1555) (6e6ba57)
- bound manifest jinja collection traversal (#1561) (23b6ca2)
- bound OCI layer extraction budgets (#1566) (5f96b42)
- bound picklescan pytorch zip members (#1569) (322c01b)
- bound protocol0 line operands (#1534) (95e27df)
- bound sevenzip member name collection (#1574) (fb36ad8)
- bound stream analysis reads (#1525) (d44deb8)
- bound weight distribution tensor extraction (#1581) (dc0051c)
- calibrate legacy PyTorch storage persistent IDs (#1652) (4a28b7f)
- calibrate onnx custom domain findings (149cde4)
- calibrate validated ONNX alternate framing (59ec990)
- ci: raise test job timeout for instrumented main lane (#1625) (94e98ca)
- clarify and enforce telemetry privacy (#1592) (33186db)
- classify pytorch zip symlink targets (#1573) (c7e1699)
- classify tar link escapes as symlinks (#1578) (edb65b2)
- classify text sidecar security findings (#1465) (a3a561c)
- cli: make streaming dry runs non-executing (c0059d8)
- close authorization evidence redaction gaps (#1596) (4606b59)
- close JIT replay review gaps (#1519) (69928bc)
- close network redaction follow-up gaps (#1518) (c6fa017)
- cloud: bound directory analysis before download (#1621) (7bf4531)
- constrain direct sharded symlink expansion (#1463) (9a9f1df)
- contain cloud object download paths (#1541) (17efed9)
- contain mlflow download return paths (#1563) (4239134)
- contextualize SafeTensors license metadata (#1661) (0904a91)
- deduplicate onnx custom domain findings (#1656) (2bca0c0)
- deps: require msgpack 1.2.1 (#1705) (d028a15)
- deps: update rust crate pyo3 to 0.29.0 [security] (#1677) (a2fe49c)
- detect explicit keras get_file tar extraction (#1556) (e15963f)
- detect flax msgpack byte keys (#1548) (e640403)
- detect operator archive Python execution paths (#1538) (ae81048)
- detect pickle binunicode8 setitem abuse (#1524) (43d2fb8)
- disable unsafe metadata deserialization (#1523) (5cf4945)
- discover hidden executorch pickle members (#1547) (1f2059f)
- dispatch logical model directory scanners (45532e3)
- distrust Keras artifact runtime versions (#1559) (fd38c3b)
- docker: preserve native architecture fallback (#1690) (8a466f4)
- docker: update Python digest and honor target architecture (#1687) (303f7c1)
- enforce MLflow acquisition budgets (#1442) (0d38924)
- enforce MLflow artifact backend allowlist (#1564) (74ebeae)
- escape text output controls (#1580) (164bbb9)
- exclude Hugging Face cache sidecars (00dcc11)
- fail closed on capped DVC outputs (#1472) (f854808)
- fail closed on invalid joblib trusted tails (#1554) (4e957b0)
- fail closed on nested protocol0 operand limits (#1536) (c018c26)
- fail closed on raw detector errors (#1457) (85e7c8c)
- fail closed on unresolved DVC outputs (#1488) (d3dd63f)
- fail closed when keras h5 lacks h5py (#1432) (0e81de7)
- fail gated Hugging Face acquisitions honestly (#1646) (8192304)
- gguf: calibrate metadata string findings (f3e77e4)
- harden cloud acquisition routing budgets (#1540) (d958807)
- harden Flax regex streaming (#1600) (0c69e69)
- harden JFrog redirect targets (#1520) (ea54e39)
- harden Keras H5 CVE coverage (#1558) (54fd488)
- harden large tokenizer JSON EOF ownership proof (#1695) (9edbaba)
- harden NeMo Hydra helper arguments (#1565) (787a1ab)
- harden NeMo Hydra I/O analysis (#1426) (6670ad3)
- harden pickle CVE stream probing (#1603) (76352d7)
- harden picklescan spec resolution (#1568) (b5b1355)
- harden R named argument detection (#1510) (5c4c4ae)
- harden streamed TAR and NeMo inspection (#1665) (c52b914)
- harden telemetry privacy redaction (#1579) (532ae59)
- huggingface: avoid probes for selection-skipped shards (#1633) (94a89df)
- inspect large ONNX models without full reads (#1664) (5befbef)
- invalidate pickle cache on source changes (#1447) (beac45c)
- isolate legacy pytorch storage controls (#1699) (1a9b556)
- jinja: require executable SSTI context (#1647) (4cd9a18)
- jit: bound alias replay before safe runpy calls (#1685) (7bd62ec)
- jit: bound passive reference replay (#1681) (e542e54)
- keep sentencepiece tokenizers out of xgboost routing (5ac9efc)
- llamafile: stream executable runtime coverage (#1622) (8d6c486)
- manifest: fail closed on scan timeout (#1615) (c769097)
- onnx: classify custom operator domains (#1614) (d5a6ac2)
- onnx: reduce weight anomaly noise (#1608) (d5ae100)
- paginate large Hugging Face inventories (e393dc0)
- pickle: bound legacy PyTorch control streams (#1619) (e407fb4)
- pickle: require source proof for framework metadata (bb38b74)
- picklescan: bound hidden ZIP probe bytes (#1624) (e8dc55e)
- picklescan: close encoded protocol0 probe gaps (#1594) (dfaedd1)
- picklescan: fail closed at nested depth limits (#1583) (5eb7390)
- picklescan: fail closed on unverifiable stream boundaries (#1521) (9cd9e67)
- picklescan: harden encoded byte probes (#1604) (f8192be)
- picklescan: ignore short base64 collisions (#1617) (1d1a93d)
- picklescan: mirror cached path importer semantics (#1683) (b948f8c)
- picklescan: preserve nested INST limit findings (#1585) (68d1d19)
- picklescan: reject padded short payload bypasses (#1626) (4edcac0)
- picklescan: resolve loaded extension exports directly (#1620) (ab6e58e)
- picklescan: safely filter inert URL metadata (#1658) (8a55653)
- picklescan: scan encoded byte literals (#1602) (21956ab)
- picklescan: validate canonical PyTorch ZIP tensor rebuilds (#1680) (2f188ad)
- preflight generic zip entry limits (#1549) (9da67c9)
- preserve active HF correlation findings (#1551) (603c782)
- preserve active HF findings (#1601) (29af2de)
- preserve default scanner read caps (#1542) (c55de21)
- preserve ONNX external data in HF streaming (#1635) (67fd0d4)
- preserve OpenVINO companions in HF streaming (#1642) (2a2aebc)
- preserve unusual docs filenames in formatter (#1533) (e1b066d)
- prevent CatBoost credential-redaction ReDoS (#1584) (493436e)
- preview Hugging Face dry-run scans (#1645) (fd40a81)
- pytorch: aggregate exact pickle opcodes (#1611) (3728964)
- pytorch: distinguish producer metadata from runtime CVEs (#1643) (beb34c6)
- pytorch: stream bounded analysis of large legacy shards (93c0e5b)
- pytorch: trust referenced storage members (#1654) (3a4f64b)
- recognize GGUF BF16 tensor type (#1632) (05443d2)
- reconcile cross-directory model shards (#1587) (b143688)
- redact authorization evidence variants (#1544) (f3ad852)
- redact CatBoost evidence secrets (#1428) (5e56d8a)
- redact exported source identifiers (#1530) (6f4407d)
- redact Keras and TensorFlow scanner evidence (#1560) (8e9d119)
- redact keras h5 lambda previews (#1435) (9830ef6)
- redact mlflow download errors (#1562) (5067f88)
- redact network finding snippets (#1438) (36f26f0)
- redact stream source urls (#1429) (77b2295)
- reduce JIT script detector false positives and negatives (#1513) (0984542)
- reject cleartext remote model sources (#1527) (6524032)
- reject jfrog folder local path collisions (#1552) (e22f4e1)
- reject symlinked CLI report outputs (#1485) (d4003a6)
- reject undersized nested pickle budgets (#1532) (0ce9bf3)
- report complete Hugging Face inventory capabilities (#1648) (d8888d1)
- require defusedxml for pmml parsing (#1570) (b8053d6)
- require explicit opt-in for PyTorch weight loading (#1582) (067dcba)
- restore cross-platform scanner baselines (#1597) (2484ac7)
- restore main CI coverage (#1606) (c81db69)
- restrict auth bearer token hosts (#1539) (838f250)
- restrict manual docker publish tags (#1526) (1abc856)
- restrict progress hook egress (#1571) (bc9419e)
- results: isolate nested member integrity hashes (#1666) (50e2df3)
- results: propagate inconclusive file coverage (#1672) (4ab592f)
- route protocol-less binary pickles (#1577) (ff68cb0)
- routing: bound tokenizer json scanner selection (#1638) (e47be19)
- routing: classify tokenizer text before binary formats (#1629) (067717d)
- routing: keep media out of serialized scanners (0a65650)
- routing: keep text assets out of Flax MessagePack (34cad20)
- routing: prefer validated safetensors framing (#1612) (2f782ba)
- rules: attribute format mismatches to s901 (#1613) (22bc654)
- safetensors: accept current tensor dtypes (#1610) (fd6f0ea)
- safetensors: accept empty tensor offsets (#1607) (9d547bb)
- safetensors: prefer bounded framing over zlib magic (#1623) (54b01e1)
- scan ExecuTorch raw payload indicators (#1545) (c37246d)
- scan model links in oci layers (#1567) (f85e0ef)
- scripts: contain corpus QA output paths (#1618) (a33b710)
- scripts: quote whitelist model ids safely (#1616) (8f57897)
- sniff Hugging Face selective downloads (#1412) (9576eb7)
- stream Flax msgpack analysis (#1589) (0c13d9e)
- stream Hugging Face SafeTensors shard headers (#1667) (e6186dc)
- stream large Flax MessagePack tensors (16e1bec)
- stream large Keras HDF5 inspection (0ff7b62)
- strictly pin picklescan maturin backend (#1531) (ac07522)
- text: contextualize tokenizer vocabulary indicators (#1653) (13431e4)
- text: deduplicate model-card indicators (#1631) (5ff4247)
- text: ignore pip version pins in documentation (#1630) (45e6d62)
- text: validate basic auth credential context (#1669) (a675581)
- tolerate picklescan reports without private metadata (cdc8b8b)
- validate hf direct url paths (#1550) (def9169)
- validate OCI layer member metadata (#1444) (a7235e1)
- validate pickle getattr reconstruction (c6c4713)
- verify rustup installer in docker builds (#1529) (51f2336)
Performance Improvements
Documentation
Bug Fixes
- require patched py7zr 1.1.3 for 7z support and preserve bounded nested format probes when it signals per-member completion
- require patched
msgpack>=1.2.1so default and optional installs avoid theUnpackerreuse crash advisory - stream large TAR and compressed-TAR model archives through TAR-specific inspection instead of generic whole-file read rejection, bound shared nested NeMo work after aggregate-budget exhaustion, preserve reachable findings at TAR and compressed-wrapper scan limits, preserve trusted HDF5 findings when overlapping TAR routing is inconclusive, prove compressed-stream ownership before bounding HDF5 user-block scans, and cap accepted compressed-wrapper zero padding
- prove large valid Hugging Face
tokenizer.jsonfiles with bounded EOF streaming so they do not fail closed as MXNet/JAX overlap, while explicitly failing closed when ownership exceeds the EOF proof cap - require executable pickle context before reporting URL-only S310 network findings while preserving reducer and loader detections
- refresh vulnerable aiohttp, cryptography, and required MLflow lock entries detected by dependency audit
- preserve native-architecture Rust installer selection for Docker builds that do not expose BuildKit's
TARGETARCHargument - require and bundle
modelaudit-picklescan>=0.1.7so root releases and source-built Docker images cannot run with the pre-hardening call-graph resolver - publish and verify coordinated
modelaudit-picklescanreleases before uploading a dependent root release - keep result-cache resolution fingerprints aligned with cached misses, symlink-sensitive lexical paths, loaded-package and namespace source-precedence contexts, bounded
FileFindersummaries, archive-validatedzipimporterstate, and startup-frozen distribution roots so shared scans cannot reuse stale origin trust or fail on metadata-only finder removal - stream Hugging Face SafeTensors shard headers with bounded range reads instead of downloading tensor payload bodies
- keep JIT alias replay linear, including multiline builtin-helper continuations, as alias state grows while preserving bounded analysis for attacker-controlled model content
- inspect oversized ONNX protobuf structure from descriptor-bound, memory- and result-bounded file-backed reads; preserve external-data security checks while explicitly reporting deferred schema, raw-detector, weight-analysis, and content-hash coverage
- treat dotted package versions in README and model-card pip install commands as informational without downgrading active URLs
- bound embedded Python assignment-line probes, deduplicate exact extraction windows, and fast-path proven passive priority references without weakening incomplete-analysis reporting
- avoid CLI crashes when redirected stdout or stderr use legacy encodings that cannot represent styled separator glyphs
- suppress canonical PyTorch tensor rebuild warnings only inside validated unloaded-runtime ZIP storage context when paired with the coordinated
modelaudit-picklescanfix, while older allowed picklescan versions continue to fail closed with the warning - keep nested archive and PyTorch ZIP member hashes separate from parent artifact integrity hashes across JSON, cache, SARIF, SBOM, and streaming scans
- suppress installed source-trusted inert Hugging Face training metadata and safe NumPy RNG-state reconstruction noise while keeping default-install, unresolved, rebound, or shadowed PyTorch ZIP framework metadata suspicious unless trusted source can be inspected
- contextualize SafeTensors license metadata so ordinary embedded license text does not produce URL or long-value noise while preserving malformed and executable metadata detections
- reconstruct bounded wrapped SafeTensors license base64 tails and fail closed on residual URL encodings before suppressing metadata URL and length findings
- validate Basic Auth credentials only in bounded authorization-header context with decodable username/password tokens
- propagate file-level inconclusive and incomplete-coverage metadata into aggregate success, strict JSON, exit-code, and cache semantics
- preserve declared ONNX external data sidecars during Hugging Face streaming scans
- inspect large Keras HDF5 models through file-backed metadata traversal instead of rejecting them at the generic whole-file read cap; aggregate
content_hashis omitted for these large file-backed HDF5 scans - paginate and bound large Hugging Face repository inventories before streaming so unfiltered scans preserve complete coverage
- dispatch logical model directories through their owning scanners, preserving bounded complete SavedModel asset probes before supplemental child-file coverage
- stream large Flax MessagePack tensor bodies by declared length without tripping the 512 MiB decode budget
- avoid critical pickle
getattrfindings for proven UltralyticsDetect.forwardreconstruction while preserving unsafe traversal controls - detect GGUF curl short-option remote fetches, ignore spaced Python attribute calls, and truncate large tokenizer metadata arrays with explicit counts
- require concrete GGUF metadata evidence for S902 findings instead of flagging benign URLs, chat-template syntax, slashes, or pipes
- deduplicate repeated ONNX custom-operator domain findings into bounded per-domain reports while preserving affected-file evidence
- avoid Hugging Face streaming body probes for declared-suffix artifacts excluded by scanner selection while preserving selected renamed content routes
- exclude Hugging Face local-dir cache sidecars from scan inventory, routing, issue locations, and SBOM components while preserving hidden artifact scanning
- keep strongly identified SentencePiece tokenizer
.modelartifacts, including custom-unknown models with disabled special tokens, out of XGBoost routing while preserving fail-closed.modelambiguity for malformed tails. - tolerate picklescan reports that omit private metadata
- stream bounded Llamafile runtime coverage across preview gaps and report incomplete runtime reads or bounds
- skip PyTorch ZIP tensor storage members referenced by
data.pklduring hidden-pickle discovery while preserving fail-closed coverage for ambiguous storage layouts - stream bounded PyTorch ZIP and legacy pickle metadata analysis for oversized legacy
.ptand.binshards instead of stopping at the generic read-size cap - distinguish PyTorch checkpoint producer-version metadata from active runtime CVE applicability, resolve runtime torch metadata only from trusted install roots, report unknown runtime applicability explicitly, carry same-revision repository SafeTensors inventory into PyTorch pickle applicability details, and preserve artifact-level pickle and tensor-structure findings
- omit isolated C&C vocabulary tokens from strongly identified tokenizer vocabularies while preserving active network and command findings
- downgrade filename/content mismatch findings only after an alternate ONNX scanner validates the protobuf format while keeping malformed, spoofed, polyglot, and incomplete routes actionable
- restrict Jinja SSTI indicators to executable template spans so prose mentions of request handling do not produce critical findings
- treat canonical storage persistent IDs as informational only after legacy PyTorch framing, storage tuples, and storage payloads validate completely
- prefer validated SafeTensors framing over invalid pickle and weak-magic collisions while retaining security-bearing pickle overlaps
- preview Hugging Face repository and direct-file scans under
--dry-runwithout downloading or scanning, backed by an opt-in pinned false-positive regression harness - make Hugging Face streaming dry runs emit metadata-only previews without artifact downloads, scanner execution, or full scan-result JSON
- report gated or unauthorized Hugging Face acquisitions as failed, inconclusive source outcomes without claiming artifact coverage, and preserve partial findings from interrupted Hugging Face streaming scans
- show Hugging Face preview access notices when selected gated files have unknown sizes
- treat known ONNX Runtime
com.microsoftoptimized-export operators as low-noise vendor metadata while preserving S1111 for unknown custom domains and ambiguous vendor claims - recognize current GGUF IQ3_S, IQ4_XS, and BF16 tensor types while preserving bounded inconclusive handling for unsupported or malformed tensor metadata
- scope both ONNX weight scanners to bounded semantic weight lineage across nested graphs, control flow, local functions, constants, Gather/Einsum, and static views; fail closed on ambiguous or sparse coverage; and evaluate extreme tails per conceptual output without suppressing repeated malicious patterns or flagging clean heavy tails
- derive PyTorch ZIP pickle opcode summaries from exact opcode evidence instead of matching substrings in finding text
- accept current SafeTensors FP8, sub-byte float, and complex tensors
- reject corpus-QA lock identifiers and paths that escape download, member, or tool-output roots
- assign ONNX custom operator domains to the dedicated S1111 framework rule instead of the HTTP-client S302 rule
- emit Hugging Face whitelist model IDs and organization summaries as safe generated Python
- preserve bounded and fail-closed SafeTensors routing when header lengths resemble compression magic
- allow equal offsets for supported empty SafeTensors tensors while preserving deterministic range checks and rejecting native size overflow
- attribute core file-type validation failures directly to S901 instead of message-matching unrelated rules
- fail closed when manifest scanning exceeds its configured timeout
- stop cloud directory analysis as soon as download size or object-count budgets are exhausted
- preserve sanitized CatBoost command context in SARIF without exposing injected or neighboring credential values
- redact values compared against sensitive keys in generic exports and literal credential comparisons in CatBoost evidence
- preserve critical PyTorch malformed-ZIP symlink findings, valid Python 3.10 streamed ZIP64 descriptors, and selected subtype findings from complete nested and concatenated HDF5 user-block ZIPs while retaining bounded fail-closed preflight checks and avoiding structure-only ZIP route probes
- classify unsafe PyTorch ZIP symlink targets as critical archive-link findings while preserving safe relative links
- recognize canonical legacy PyTorch pickle-stream boundaries without treating raw tensor storage as incomplete pickle, binary-tail, or CVE coverage
- restore pickle CVE scan throughput, reprobe malformed stream separators, and route four-byte protocol-0 Joblib operands correctly
- bound manifest embedded-Jinja template collection while preserving findings across deep branches, cycles, and shared YAML aliases
- bound Jinja static render analysis and fail closed on CPU-heavy aliased, recursive, container-wrapped, and arithmetic range probes when sandbox workers are unavailable
- restrict auth bearer-token validation to trusted Promptfoo API hosts unless custom hosts are explicitly configured
- escape terminal and Unicode formatting controls in human-readable CLI output
- disable unsafe Joblib and NumPy object metadata deserialization
- keep concrete active execution, runtime-extension, and blacklist findings from being downgraded by Hugging Face whitelists
- keep same-fragment command/network correlations and relayed fail-closed findings active across Hugging Face whitelists
- validate Joblib NumPy wrapper state and scan resumed pickle opcodes around raw array payloads without flagging inert array bytes.
- bound CatBoost command-evidence redaction work and cover distant, shell-concatenated, wrapped, and netrc curl credentials
- use credential-free, cross-platform cloud routing filenames without changing native object-key suffix semantics
- encode native cloud object keys into collision-resistant, prefix-safe Windows paths and reject out-of-target listings
- fail closed on unsafe cloud object paths, parent-directory swaps, and download destination aliases
- discover extensionless pickle payloads inside ExecuTorch ZIP archives with bounded structural probing, including repeated protocol-0 comment-token evasions
- report TAR external link escapes with the dedicated symlink rule code, resolve link targets from their correct archive bases, and avoid retaining passing checks for benign link floods
- bind direct sharded-model cache entries to sibling shard and selected model configuration content fingerprints, and strengthen cache configuration hashes
- fail closed on PMML XML parsing when defusedxml is unavailable instead of using the stdlib parser
- reject ambiguous, lossy, SDK-invalid, or traversal-bearing Hugging Face direct file URLs, redact rejected URL secrets, and preserve platform-valid filenames
- scan safe OCI layer links with model-looking member names instead of treating link metadata as complete coverage
- preserve scanner read caps when core max_file_size is unlimited
- reject untrusted JFrog redirect hostnames unless explicitly allowed, block non-public IP targets, suppress ambient netrc credentials, and isolate redirect authentication and cookies
- restrict manual Docker publishes to validated immutable version tags and their matching Git release refs before registry login or push
- harden cloud acquisition size caps, HTTPS/R2 auto-default routing, and directory metadata failures
- detect operator attrgetter, itemgetter, and methodcaller archive-member Python paths to command execution while preserving benign accessor names
- redact Keras and TensorFlow scanner detail fields that echo model-controlled configs, code indicators, archive members, and external references.
- route security-relevant protocol-less binary pickle streams through pickle analysis even when file suffixes are misleading
- avoid routing complete benign cloud objects as protocol-less pickle prefixes when they exactly consume the content-sniff budget
- redact folded, placeholder-adjacent, proxy, and camel-case authorization evidence with scheme-bearing values without hiding benign counters
- bound Keras ZIP config traversal for CVE detectors and fail closed when config.json coverage budgets are exhausted
- redact MLflow registry, source, telemetry, and client exception credentials before logging, printing, or analytics export
- bound 7z member-name collection before archive entry-limit failures
- bound remote streaming-analysis reads and report actual received-byte coverage for truncated objects
- avoid sending raw model identifiers, source paths, object keys, issue locations, or free-form errors in telemetry
- cover Keras H5 callable metadata and module references, align CVE-2025-1550 attribution, and scope HDF5 external-reference checks to Keras weight trees
- require explicit boolean opt-in before weight-distribution scans call torch.load and bound primitive PyTorch ZIP fallback extraction
- fail closed when OCI layer TAR metadata, member counts, or cumulative extracted bytes exceed inspection budgets
- fail closed on JFrog folder downloads whose selected artifacts use unsafe, colliding, or overlapping local paths
- keep complete bounded UTF-8 text assets out of Flax MessagePack routing while preserving fail-closed scalar-stream coverage
- detect dangerous textual byte keys in Flax MessagePack checkpoints
- bound Joblib decompression output to the configured scanner read budget
- redact credential-bearing source identifiers in exported SARIF and SBOM reports
- reconcile validated streamed shard families across staging directories and add an explicit opt-in for local cross-directory shards
- stream Flax MessagePack containers with bounded traversal, object, and metadata-key handling instead of a whole-file size cutoff
- bound ExecuTorch ZIP metadata and member scans while preserving eligible pickle detections across archive limits and mutations
- close JIT replay alias, probe-budget, and compound-clause context gaps without suppressing dangerous browser or native-library calls
- detect
BINUNICODE8literals and bounded concatenated-stream abuse in pickle CVE-2026-24747 SETITEM analysis without treating byte literals asSTACK_GLOBALnames - reject MLflow downloads that replace or escape private staging, hide behind directory links, expose special files, or retain external hardlinks, and report safety refusals without success telemetry
- scan raw payload indicators inside signature-valid ExecuTorch binaries and launcher-prefixed archives before reporting them clean
- detect Keras get_file tar extraction from effective call arguments without relying on URL suffixes
- reject cleartext HTTP cloud storage and PyTorch Hub model sources
- preserve dangerous JIT embedded-Python findings after benign member overwrites while bounding replay and suppression analysis
- treat Keras StringLookup external vocabularies with fixed-looking archive metadata as runtime risk instead of trusting artifact-supplied versions
- fail closed when capped DVC pointer outputs are not otherwise covered, change during verification, exceed bounded tail verification, or exhaust shared scan budgets
- preserve registrable network domains and redact delimiter-split credentials in bounded finding evidence
- preserve executable text-sidecar network findings for f-string calls, standard command wrappers, port-qualified Docker registries, and bounded xargs downloads while keeping prose references informational.
- require explicit public progress hook egress hosts and reject internal webhook and SMTP destinations before sending scan details.
- stabilize cache identity capture for compressed wrapper scans on Darwin
/privatepath aliases and during unrelated temporary-file churn. - fail closed on over-entry, oversized, inconsistent, hidden-entry, or trailing-record generic ZIP directories before
zipfilematerializes their entries, keep PyTorch ZIP budgets and loading on one descriptor, and validate generic ZIP symlinks against archive-root containment. - detect interpolated Hydra helper configs, legacy Hydra global-state aliases, and unsafe local or remote NeMo model-loader paths.
- bound per-tensor and cumulative weight-distribution extraction before materializing PyTorch, HDF5, TensorFlow, and ONNX payloads
- keep bounded ExecuTorch ZIP snapshots seekable on Python 3.10 so benign and malicious pickle members remain analyzable
0.2.47 (2026-06-05)
Bug Fixes
- bind cache reads and writes to scanned file identity (#1458) (860adab)
- redact MetaGraph evidence previews (#1473) (58139d9)
- redact Torch7 evidence examples (#1467) (646857b)
0.2.46 (2026-06-05)
Bug Fixes
- address runpy review edge cases (#1401) (995f978)
- analyze ambiguous protobuf routing candidates (#1302) (411b6ee)
- avoid ambient TensorFlow proto imports (#1406) (601003d)
- avoid duplicate sharded scans and preserve metadata (#1231) (83a0ce5)
- avoid framed process string false positives (#1400) (9aae65a)
- avoid pickle meta-path source probing (#1493) (a31df76)
- block 7z symlinks before extraction (#1462) (73152a0)
- block torch.load on vulnerable prereleases (06125e5)
- bound directory metadata extraction (#1470) (3dd9ceb)
- bound GGUF declared collections (#1316) (3ceb138)
- bound jax and flax metadata scans (#1500) (1f794df)
- bound jinja sandbox render probes (#1419) (6a6534b)
- bound native picklescan state simulation (#1501) (f4c9cdf)
- bound OCI layer decompression (#1443) (fd76fb1)
- bound Orbax directory checkpoint scanning (#1414) (22a9ffa)
- bound PyTorch ZIP version probes (#1512) (196fb46)
- bound SavedModel graph traversal (#1491) (b42fffb)
- bound SavedModel keras metadata parsing (#1466) (b2eddc4)
- cache: key advanced shard allowlists (#1248) (336148a)
- cap PyTorch ZIP entry processing (#1455) (e74da5b)
- ci: avoid performance gating in Windows nightly (#1264) (c01b42a)
- classify incomplete CatBoost analysis correctly (388565b)
- classify incomplete OCI layer scans correctly (#1291) (25aae73)
- classify incomplete pickle analysis and stream coverage (#1310) (e20518f)
- classify incomplete PMML analysis correctly (#1293) (a3b2cfe)
- classify incomplete R serialized analysis correctly (#1312) (9439adc)
- classify incomplete RKNN and Torch7 analysis correctly (#1289) (6d0ad24)
- classify incomplete Skops coverage correctly (#1298) (d618584)
- classify incomplete TAR member coverage correctly (#1299) (0cb11b1)
- classify incomplete TorchServe analysis correctly (#1297) (f443b02)
- classify incomplete weight analysis correctly (#1313) (e4138c1)
- classify incomplete ZIP and Keras coverage correctly (#1300) (c350ab9)
- classify PyTorch binary code patterns as findings (#1497) (e9c6c0a)
- classify sevenzip probe limits as inconclusive (#1296) (d7e1ad1)
- classify unavailable binary artifact reads correctly (#1305) (bc4e6b2)
- classify unavailable CNTK and LightGBM reads correctly (#1303) (26fcf41)
- classify unavailable Joblib reads correctly (#1309) (5b56384)
- classify unavailable manifest and text reads correctly (#1307) (5b50c71)
- classify unavailable metadata reads correctly (#1308) (fa4cdb0)
- classify unavailable MetaGraph reads correctly (#1304) (c00de0b)
- classify unavailable MXNet reads correctly (#1301) (a7b8e27)
- classify unavailable serialized model reads correctly (#1306) (113ba27)
- classify unavailable TFLite analysis correctly (#1311) (c3e1607)
- cloud: enforce size caps on cached downloads (#1507) (8f38004)
- confirm ONNX python_operator findings against the parsed graph (#1254) (#1260) (beb71cd)
- contain SBOM symlink hashing (#1476) (f147ebc)
- core: group HF cache shard symlinks (#1252) (91f833d)
- cover embedded browser and ctypes edges (#1402) (ce31f2f)
- cover patched PyTorch weight-load versions (#1482) (4c0bdb3)
- detect asyncio subprocess launches in embedded Python (#1366) (f520c0d)
- detect disguised PyTorch ZIP executables (#1318) (00bc356)
- detect dynamic picklescan protocol hooks (#1375) (400c132)
- detect dynamic TorchServe handler primitives (#1471) (5c28aee)
- detect embedded runpy execution calls (#1372) (1f9a8d5)
- detect embedded webbrowser launch calls (#1373) (f1b2df6)
- detect Keras weights-only external HDF5 refs (69810c2)
- detect namespace-hidden archive Python calls (#1317) (ae2deb3)
- detect NeMo torch extension targets (edb642c)
- detect newline-separated picklescan calls (#1481) (8dcbbb1)
- detect obscured GGUF chat templates (#1315) (8d184c9)
- detect os process launches in embedded Python (#1363) (642fd4c)
- disable sampled large-file scan caching (#1459) (0ddbb93)
- enforce cloud download size caps (#1407) (10e1342)
- enforce Hugging Face download budgets (#1413) (1587131)
- enforce huggingface file size budget (#1410) (7f55f52)
- enforce JFrog download size budgets (#1416) (9cb392f)
- enforce PyTorch Hub download budgets (#1452) (d8e74fa)
- fail closed on embedded Python JIT budget gaps (#1502) (09a4844)
- fail closed on embedded weights without h5py (#1433) (463bc2c)
- fail closed on empty Hugging Face repo listings (#1411) (1cbb8aa)
- fail closed on encoded nested probe cap (6633dac)
- fail closed on executable ZIP scanner gaps (#1487) (889db72)
- fail closed on hf streaming extensionless listings (#1492) (d70dec4)
- fail closed on incomplete Flax traversal (#1295) (335d06c)
- fail closed on incomplete JAX analysis (#1292) (a3558f1)
- fail closed on incomplete PyTorch ZIP scans (65faa90)
- fail closed on malformed SavedModel metadata (#1464) (60d5307)
- fail closed on NumPy object pickle skips (#1460) (59c52b1)
- fail closed on oversized standalone Jinja templates (#1283) (76f221e)
- fail closed on partial cloud metadata (#1404) (70db661)
- fail closed on pickle import reference truncation (#1449) (5ddac28)
- fail closed on protocol 5 pickle buffers (#1450) (e696a1f)
- fail closed on StringLookup external vocab metadata (#1484) (b994dc3)
- fail closed on truncated CNTK string analysis (#1290) (c6ee60f)
- fail closed on unavailable Keras ZIP scanner (#1474) (0183a9e)
- fail unsafe keras h5 lambda ambiguity (#1434) (548d0f2)
- flag import-only custom pickle globals (#1499) (ca3a476)
- flag keras fixed-boundary prereleases (#1431) (0f6ea92)
- flag native keras config modules (#1430) (440fe18)
- flag oversized pickle frames as tampered (#1448) (c4758fd)
- harden asyncio subprocess review follow-up (#1398) (31077f3)
- harden embedded ctypes/browser analysis after #1402 (#1403) (0d37ebc)
- harden embedded Python builtin alias detection (#1420) (fadceb3)
- harden Keras ZIP external reference analysis (#1423) (a0e00cf)
- harden Keras ZIP version attribution (#1424) (57ca7f3)
- harden Keras ZIP wrapper traversal (#1425) (713eb4d)
- harden late embedded Python replay analysis (#1446) (6b625ff)
- harden legacy JAX checkpoint routing (#1397) (4db8d50)
- harden mixed Keras H5 Lambda analysis (#1422) (6d1ba2e)
- harden MXNet overlap routing after merge audit (#1378) (4e55dd0)
- harden NeMo Hydra interpolation analysis (#1427) (099417a)
- harden PyTorch Hub streaming cleanup (#1454) (2f11b7c)
- harden standalone Keras H5 external reference analysis (#1421) (64e643f)
- harden structured Jinja size handling (#1418) (1165a0e)
- honor compatible header alias routing (#1272) (ee9611e)
- include supported PyTorch Hub artifacts (#1453) (a3e1616)
- keep docker digest updates CI-compatible (#1258) (406ed50)
- keep shard siblings within scan root (a1efccb)
- keras: redact authorization detail aliases (#1511) (18de054)
- manifest: fail closed on cloud URL read errors (#1396) (cf1da88)
- mark compressed partial scans inconclusive (#1286) (39b8f58)
- mark oversized structured Jinja templates incomplete (6662d3d)
- mark truncated pickle binary tails incomplete (#1445) (cae15c4)
- nemo: fail closed on linked load semantics (#1377) (b952e4b)
- omit SafeTensors custom metadata from security view (#1440) (23e7c44)
- onnx: scan function default graphs (#1273) (10c57ed)
- onnx: scan nested Python operators (#1265) (40850e3)
- preflight 7z extraction budgets (bf7f3de)
- preserve Flax routing across ambiguous prefixes (#1379) (b3438b8)
- preserve visible JAX findings in oversized JSON (#1380) (39afcf0)
- redact code evidence in scanner findings (#1495) (1c2855e)
- redact compound credential evidence (4a0a364)
- redact flax msgpack evidence (#1409) (66c55cb)
- redact Keras evidence secrets (#1475) (37eda4e)
- redact keras zip finding details (#1436) (b90d08d)
- redact LightGBM evidence excerpts (#1437) (fed2313)
- redact metadata secret previews (#1439) (a96f83a)
- redact network URL path tokens (fa5fd17)
- redact R serialized executable samples (#1456) (7c3e10c)
- redact SavedModel decoded previews (ba6eaa1)
- redact secret detector contexts (923f6af)
- reject unsafe JFrog credential targets (#1490) (11d8978)
- repair nightly and docker ci (#1255) (4c8fa7b)
- report Keras external refs despite metadata (#1478) (0c63514)
- report Keras H5 external refs despite metadata (#1483) (5997e06)
- require ETags for cloud cache hits (1a8e39d)
- resolve follow-up quality findings (#1222) (2968961)
- restrict auth token API hosts (#1486) (9ccddc5)
- restrict JFrog credential forwarding (8287edd)
- retain oversized renamed SafeTensors candidates (#1285) (64efefa)
- route disguised llamafiles and classify preview read failures (#1267) (ad55249)
- route disguised torch7 payloads by content (#1268) (9ba9cd1)
- route extensionless XGBoost and classify incomplete analysis (#1276) (46bffb4)
- route large and renamed Flax MessagePack checkpoints (#1280) (40766c4)
- route padded and renamed JAX JSON checkpoints (#1281) (62270b4)
- route prefixed renamed ONNX payloads by structure (#1287) (b022bbb)
- route renamed binary formats and classify ExecuTorch read failures (#1271) (c86dd85)
- route renamed CNTK and LightGBM payloads (#1269) (877aa10)
- route renamed MXNet symbol graphs by structure (#1278) (1c0b3c5)
- route renamed NeMo archives by structure (#1274) (bf96228)
- route renamed R workspace artifacts (#1322) (e004deb)
- route renamed TensorFlow protobuf models by structure (#1284) (3327c39)
- routing: avoid false Flax overlap on complete pickles (#1506) (6510430)
- routing: preserve Torch7 findings in Llamafile polyglots (#1376) (2e95c88)
- run text sidecar security detectors (#1498) (9e3f581)
- scan duplicate executorch pickle members (#1408) (5b4c616)
- scan hidden compressed payload risks (#1320) (77ec76f)
- scan late PyTorch binary executable signatures (#1451) (bd2782c)
- scan namespaced OpenVINO layers (#1314) (59794d6)
- scan nested ONNX external initializers (d3a9130)
- scan nested ONNX external tensor references (#1399) (5071995)
- scan padded SavedModel protobuf strings (#1469) (b26c000)
- scan protocol zero JAX checkpoint pickles (aa580c6)
- scan raw nested pickles in unicode strings (#1461) (4278da9)
- scan RKNN safe metadata values (cd833c2)
- skip hashing files over scan size limit (#1441) (2b46042)
- sniff cloud content before selective skip (#1405) (90c5627)
- sniff JFrog folder content before selective skip (#1417) (372a72a)
- strip jfrog credentials on redirects (#1415) (6869361)
- terminate call-graph alias fixpoint on oscillating rebinds (#1247) (#1259) (89895a4)
- torch7: restore ASCII serialized routing (#1263) (a0cf7f0)
- treat Keras fixed-version prereleases as vulnerable (ae76cb9)
Performance Improvements
- mmap TFLite files for zero-copy FlatBuffer scanning (#1503) (ce3b4f4)
- restore realistic benchmark suite (#1223) (9c36efb)
- reuse call graph analysis in directory scans (#1266) (2f01ddf)
Documentation
Bug Fixes
- prevent sharded-model scans from accepting changed family membership, stale shard identities, or unsafe aliases
- invalidate cached pickle call-graph results when analyzed Python sources, search paths, or loaded module origins change
- harden CLI scan, SBOM, metadata, and scanner-catalog output writes against links, reparse points, and special files; preserve Windows ownership and ACLs, and reject EFS-encrypted destinations that cannot be replaced without changing recipients
- distinguish valid R call/index argument tags from malformed credential assignments and fail closed on incomplete function bodies
- require every concrete non-local MLflow artifact target to match
MODELAUDIT_MLFLOW_ALLOWED_ARTIFACT_URIS, including artifact-path-specific entries, while safely composing local overlays and binding downloads to the validated repositories - validate OCI layer member and link metadata without suppressing regular-file payload scans, while preserving valid container-root symlinks
- prevent cache identity checks from accepting temporary higher-ancestor path swaps
- preflight MLflow artifact sizes and copy supported local repositories under hard byte limits, rejecting unsafe paths, size drift, and backends that cannot enforce the configured download budget
- omit attacker-controlled Keras H5 Lambda names, module/function references, source, bytecode, code-analysis, malformed config, compiler-error, nested-key, and fake wrapped-layer evidence; clean up temporary Python compiler artifacts; fail closed on malformed scalar functions; and avoid substring-only malformed-source warnings
- fail closed on standalone and Keras ZIP HDF5 scans when
h5pyis unavailable, including content-routed and extensionless user-block files, while preserving overlapping format findings and invalidating stale cached results - fail closed when raw secret, JIT, or network detector analysis errors occur, and when memory-mapped files change during scanning
- mark unresolved DVC outputs as incomplete scan coverage instead of scanning pointer text as clean
- redact secret-bearing TensorFlow MetaGraph executable previews and correlation examples
- redact credential-shaped Torch7 evidence and detect execution primitives across chunk boundaries and alternate Lua syntax
- bind cache reads and writes to complete file and pathname identities captured before scanning
- bind SBOM hashing to stable scan-root descriptors and omit hashes for outside, swapped, or missing local symlink targets
- detect native execution modules and nested serialized callables in Keras configs without promoting unimportable dotted native-module paths
- classify noncanonical Keras versions inside wholly vulnerable numeric ranges and avoid over-attributing wildcard fixed lines
- preserve selected content-routed and exact-name cloud/JFrog artifacts, structurally filter renamed JFrog ZIPs, share cloud probe and download budgets, isolate selective directory caches, and exclude confidently unselected shared-suffix formats
- detect TorchServe MAR handler execution primitives reached through dynamic imports, namespace lookups, literal selection, callbacks, and partial callables without flagging statically unreachable paths
- omit sensitive LightGBM model excerpts and network values from finding evidence
- fail closed when TensorFlow SavedModel graph traversal exceeds bounded node or function budgets
- restrict bearer-token authentication to validated HTTPS base API hosts before requests and preserve prior credential routing when config persistence fails
- redact credential-bearing and unrelated URL context from network and C&C finding snippets while preserving nested query and fragment endpoints
- enforce JFrog file and folder download size budgets before and during remote artifact transfer, and bound Storage API metadata responses
- validate and bound OCI gzip framing and raw TAR metadata before parsing layers, preventing decompression-budget dilution and malformed-trailer bypasses
- fail closed on embedded Keras HDF5 weights when
h5pyis unavailable while preserving full-payload, generic, and concatenated user-block security findings - omit raw SafeTensors custom metadata values from security-only output while retaining precise redacted risk flags and rejecting malformed metadata maps
- block 7-Zip symlinks, junctions, and ambiguous duplicate member names before extraction
- add aggregate file, byte, and depth budgets to directory metadata extraction and reject non-regular entries and symlink targets
- redact and detect secrets in R serialized executable samples across native assignment syntax
- redact authorization aliases across structured, malformed, subscripted, and R scanner evidence
- scan padded TensorFlow SavedModel protobuf scalar and repeated string attributes past the legacy 10 KB injection-check window
- mark malformed SavedModel
keras_metadata.pbanalysis as inconclusive instead of a clean scan - fail closed on pickle protocol 5
NEXT_BUFFERopcodes instead of reporting clean coverage - bound
keras_metadata.pbparsing in SavedModel scans, fail closed when the budget is exceeded, and continue analysis when a system hash policy disables MD5 - fail closed when structurally recognized Keras ZIP scanners are unavailable while retaining generic ZIP security findings
- redact sensitive decoded previews in TensorFlow SavedModel collection, PyFunc, and Keras metadata findings
- report proven oversized pickle
FRAMElength mismatches as structural tampering without misclassifying incomplete frame reads - fail closed on novel standalone picklescan import/callable metadata truncation without masking operational read errors or repeated benign imports
- skip scan-result caching for sampled large-file fingerprints
- classify high-confidence active code patterns in PyTorch binary artifacts as security findings so scan exits reflect them
- run bounded secret and network-content checks for ML text sidecars and prefer strict LightGBM content over native Flax suffixes
- bound Flax MessagePack decoding/traversal and Orbax metadata JSON parsing so oversized JAX/Flax checkpoints fail closed
- avoid false inconclusive Flax overlap results for complete pickle payloads with no trailing data
- preserve dangerous embedded-Python builtin detection across aliases, builtin namespaces, and control flow
- bound Keras ZIP HDF5 external-reference inspection and evidence, preserve hard-link cycle traversal, and flag malformed Lambda metadata
- fail closed on noncanonical Keras ZIP Lambda and external-reference versions
- scan ONNX external data references in sparse initializers, tensor-valued attributes, and function defaults
- avoid false-positive process-launch findings for parsed framed Python string literals
- detect dangerous Python calls retrieved through module namespace dictionaries in ZIP and TAR members
- fail closed on malformed Keras version suffixes used for CVE boundary checks
- fail closed when executable ZIP subtype scanners are unavailable
- reject local, plaintext, and redirecting JFrog credential targets
- detect embedded Python
os.exec*,os.spawn*,os.posix_spawn*, andos.startfileprocess-launch calls in archives and JIT-scanned content - detect embedded Python
asyncio.create_subprocess_*calls and resolved JITsubprocesslaunch aliases - detect embedded Python
runpy.run_module,runpy.run_path, andrunpy._run_module_as_maindynamic-module execution calls - preserve embedded Python runpy, webbrowser, and ctypes findings across continued imports, late aliases, and bounded tail-window extraction gaps
- preserve late
runpyexecution findings across bounded state updates, restoration, and builtin shadowing - mark embedded Python/JIT byte and snippet budget exhaustion as incomplete coverage instead of clean scans
- detect embedded Python
webbrowserlaunches andctypesnative-library loads in archives and JIT-scanned content - resolve embedded
ctypesloads through more CDLL-subclass construction forms (__new__returning insidetry/for/while/with,super()/*argsinitializer forwarding) and indirect loader/controller bindings (conditional, boolean, walrus, and loop-bound expressions) - honor benign loader/controller member overwrites spelled as
setattr(..., **{})or starredsetattr(*(...)) - fail closed on deeply nested embedded Python members and bound embedded-snippet alias probing so crafted archives cannot crash or stall the scan
- scan dangerous RKNN safe-key metadata values instead of suppressing the whole key-value string
- scan ONNX external data initializers in nested graphs, functions, and training graphs
- route protocol-0 JAX checkpoint pickles through pickle opcode security checks
- bound Orbax directory metadata parsing and checkpoint entry enumeration before scanning JAX checkpoints
- harden legacy JAX checkpoint pickle routing against bounded-prefix bypasses and benign sidecar false positives
- detect dangerous Python calls retrieved or installed through module namespace dictionaries in ZIP and TAR members, while avoiding comprehension-local false positives
- preflight and stream-enforce cumulative SevenZip extraction budgets before writing oversized archives
- mark oversized structured JSON/YAML Jinja template fields as incomplete coverage instead of clean
- bound Jinja sandbox safety probes so render amplification fails closed instead of exhausting scanner resources
- harden structured JSON/YAML/GGUF Jinja template extraction against oversized values, nested containers, and colliding template paths
- redact capability tokens embedded in network URL path segments
- redact Flax/JAX MessagePack scanner samples, contexts, key paths, structured fields, metadata, and errors
- redact secret previews and URL path credentials from metadata scanner findings
- redact secret-shaped dictionary keys from embedded-secret detector finding contexts
- redact compound credential names and malformed userinfo URLs in scanner evidence
- redact secret-bearing JAX/Orbax, JIT, PyTorch ZIP, and explicit model-network evidence before serializing findings
- restrict JFrog credential forwarding to explicitly trusted HTTPS hosts
- include content-routed renamed JFrog folder artifacts in selective downloads with fail-closed bounded probes
- strip JFrog credentials from untrusted redirect hops during artifact and Storage API requests
- enforce direct Hugging Face file
--max-sizebudgets before downloading - scan duplicate and case-varied ExecuTorch pickle ZIP members without shadowable-name or metadata-routing bypasses
- refresh cloud cache entries that cannot be proven within the configured download size limit
- enforce automatic cloud download size limits when remote size metadata is missing or late-bound
- avoid importing attacker-shadowed TensorFlow protobuf packages during static scanning
- inspect every parsed GGUF chat template when duplicate or trailing malformed metadata could otherwise hide SSTI payloads
- bound GGUF declared metadata and tensor collections, and cap reported tensor summaries, so oversized structures fail closed without exhausting scanner resources
- redact secret-shaped dictionary keys from embedded-secret detector finding contexts
- redact compound credential names and malformed userinfo URLs in scanner evidence
- restrict JFrog credential forwarding to explicitly trusted HTTPS hosts
- redact compound credential names and malformed userinfo URLs in scanner evidence
- restrict JFrog credential forwarding to explicitly trusted HTTPS hosts
- block weight distribution
torch.loadon PyTorch prerelease, dev, and unknown versions before deserialization while preserving final, local, and PEP 440 post-release patched builds - fail closed on unverified Keras ZIP
StringLookupvocabulary paths and redact remote URL evidence - fail closed when cloud directory metadata cannot be read for every listed object
- treat normalized PEP 440 prereleases of the fixed Keras 3.11.3 CVE-2025-49655 boundary as vulnerable without allowing long local-version metadata to downgrade attribution
- treat prereleases of fixed Keras ZIP CVE-2026-1669 versions as vulnerable
- redact reversible secret evidence from CatBoost findings and validate IPv4/IPv6 network indicators
- detect and safely bound NeMo Hydra process-execution, native-loader, network, and file-access callable targets, including trusted-namespace import/cache helpers, repeated YAML aliases, and NumPy file writers
- fail closed on interpolation-bearing NeMo Hydra
_target_selectors whose resolved callable cannot be verified - scan and globally bound Keras ZIP wrapper-owned nested layers while preserving custom namespace warnings
- detect external references in weights-only Keras HDF5 layouts without Keras metadata
- bound standalone Keras HDF5 layout and external-reference analysis, and distrust artifact-controlled versions
- inspect mixed dict/list Keras HDF5 Lambda bytecode with bounded, marshal-aware analysis
- fail closed on malformed Keras HDF5 Lambda functions, code-loading callbacks, and non-allowlisted framework references
- restrict JFrog credential forwarding to explicitly trusted HTTPS hosts
- classify unavailable metadata document reads and timed-out metadata scans as operationally incomplete rather than security findings
- route renamed structured JAX/Orbax JSON checkpoints, conservatively report observable bounded-prefix threats, and fail closed for oversized identified metadata
- classify Flax MessagePack recursion-limit analysis gaps as inconclusive coverage
- classify incomplete JAX/Orbax metadata, pickle, and NumPy analysis as inconclusive coverage
- route renamed structured JAX/Orbax JSON checkpoints and fail closed for oversized identified metadata
- route renamed structurally valid Flax/JAX MessagePack checkpoints through bounded, fail-closed security analysis
- preserve Flax/JAX MessagePack routing under skipped text/configuration suffixes and pickle-shaped prefixes with bounded fail-closed ambiguity handling
- avoid emitting sensitive scanner finding or loader error payloads in logs
- fail closed when PyTorch ZIP analysis cannot complete configured blacklist inspection or a required scan phase
- stream Hugging Face files through case-insensitive suffix filtering with bounded extensionless coverage
- fail closed when standalone Jinja2 templates exceed the configured analysis size limit or cannot be decoded as UTF-8 text
- classify bounded, unreadable, or malformed PMML analysis gaps as inconclusive instead of security findings
- classify unavailable Joblib reads as inconclusive rather than security findings
- avoid repeatedly scanning sharded model families during directory scans
- keep shard sibling discovery within the requested scan root
- preserve per-shard metadata when aggregating sharded model families
- prevent picklescan call-graph alias cycles from hanging scans
- preserve HuggingFace snapshot shard paths while grouping cache-backed families
- enforce Hugging Face repository
--max-sizebudgets before selected snapshot or streaming downloads begin - fail closed when Hugging Face repository listings contain no recognized scannable files instead of downloading the full repository
- include bounded content-routed Hugging Face repository files in selective downloads, preserve local filename-based false-positive guards, pin probes and downloads to one immutable revision, redact signed transport errors, enforce acquisition deadlines across transfer process groups, and fail closed when repository coverage cannot be completed safely
- stop flagging a false-positive ONNX Python operator when tensor weight bytes coincidentally spell
PyOp - classify unavailable manifest and ML text reads as inconclusive rather than security findings, including routing, preflight, and stale cache transitions
- classify unavailable manifest cloud-reference inspection as inconclusive rather than reporting complete coverage
- detect Python operators declared in nested ONNX graphs, functions, and function-default graphs
- distinguish ASCII-serialized Torch7 artifacts from plain PyTorch source text
- route renamed R workspace artifacts only from complete workspace serialization headers without promoting text near-matches
- report incomplete R serialized coverage without treating extraction ceilings alone as suspicious payloads, and preserve detection across printable-chunk boundaries
- mark compressed-wrapper partial-analysis outcomes explicitly inconclusive
- scan decompressed Python and content-disguised executable payloads through bounded security checks without caching ephemeral inner files
- detect executable PyTorch ZIP sidecars hidden behind ordinary filenames while excluding raw tensor-storage bytes
- fail closed and cap downstream scanning, metadata listings, and version metadata probes for PyTorch ZIP archives, preserve parent structure attribution across nested entry limits, and retain deadline and prefixed-layout metadata handling
- scan 7-Zip Python members and content-disguised executable sidecars through shared archive security checks
- include supported non-PT artifacts linked from PyTorch Hub model pages while rejecting format-changing redirects and non-artifact responses
- enforce
--max-sizewhile streaming PyTorch Hub model weights - enforce
--max-sizewhile downloading PyTorch Hub models in normal acquisition mode - detect structurally valid executable payloads throughout PyTorch binary files while bounding context analysis and findings
- skip non-numeric weight metadata and report incomplete weight-distribution analysis accurately
- classify unavailable Paddle, NumPy, PyTorch binary, and SavedModel reads as inconclusive rather than security findings
- fail closed when scanner selection disables required NumPy object-dtype embedded pickle analysis
- classify unavailable CoreML, SafeTensors, and TensorRT reads as inconclusive rather than security findings
- classify unavailable TensorFlow MetaGraph reads as operational errors rather than security findings, including stale cache transitions
- classify unavailable CNTK and LightGBM reads as inconclusive rather than security findings
- route renamed and unknown-field-prefixed CoreML models, including valid unknown groups, reordered fields, and bounded routing candidates, through custom-code and metadata analysis
- avoid inconclusive protobuf-candidate noise for fully inspected scalar-only text and Keras-owned JSON members while preserving binary-tailed candidates for analysis
- preserve archive member incomplete-outcome reasons when nested tentative analysis also fails closed
- route renamed TensorFlow SavedModel and MetaGraph protobufs through unsafe-operation analysis
- route renamed ONNX protobuf models with prefixed unknown fields through content analysis and fail closed on unresolved or incomplete structure
- preserve ambiguous budget-exhausted protobuf candidates for tentative analysis without misclassifying non-ONNX payloads
- classify unavailable ZIP traversal, member, manifest-less TorchServe handler, and Keras artifact scan coverage as inconclusive while preserving archive-depth security findings
- classify unavailable TAR traversal and member scan coverage as inconclusive while preserving depth-limit security findings
- classify unavailable Skops member and schema coverage as inconclusive rather than security findings
- preserve Skops nested Python-member detection for high-risk calls reached through
__getattribute__ - classify bounded, unreadable, or unparseable TorchServe MAR analysis gaps as inconclusive rather than security findings
- detect manifest-declared TorchServe extra files and PyTorch ZIP members disguised with executable content
- classify incomplete SevenZip coverage as inconclusive and avoid caching temporary extracted members
- classify uninspected OCI layers and members as inconclusive analysis instead of security findings, without caching extracted temporary members
- route renamed ONNX protobuf models with prefixed unknown fields through content analysis and fail closed on unresolved or incomplete structure
- mark compressed-wrapper partial-analysis outcomes explicitly inconclusive
- retain oversized renamed SafeTensors candidates for bounded fail-closed analysis
- route renamed TensorFlow SavedModel and MetaGraph protobufs through unsafe-operation analysis
- detect and scan signature-valid CNTK and LightGBM payloads even when renamed with misleading suffixes
- mark CNTK read failures and string-extraction limits as inconclusive analysis while retaining strict CNTK ownership and fail-closed ambiguous Flax overlap coverage
- detect and scan signature-valid RKNN, TFLite, and ExecuTorch payloads under non-conflicting renamed suffixes while preserving owned routes, and classify unavailable ExecuTorch reads as inconclusive
- mark CatBoost text-fragment extraction limits and unavailable reads as inconclusive analysis
- mark RKNN and Torch7 string-extraction limits and unavailable reads as inconclusive analysis
- classify unavailable TFLite parsing coverage as inconclusive rather than a security finding
- classify unavailable MXNet artifact reads as inconclusive rather than security findings
- detect dangerous OpenVINO layers inside namespace-qualified IR models
- classify unavailable pickle reads and stream coverage as inconclusive rather than security findings
- route renamed structurally valid MXNet symbol graphs through existing suspicious-reference analysis
- harden renamed MXNet symbol routing with fail-closed bounded ambiguity and XGBoost overlap handling
- restore content routing for extensionless XGBoost UBJSON models and classify unavailable or undecodable XGBoost reads as inconclusive
- detect NeMo Hydra targets that invoke PyTorch C++ extension loaders
- route renamed TAR-backed NeMo archives with relative archive-root model configs through Hydra
_target_analysis while retaining generic embedded-member checks - avoid reporting non-extractable forward-hardlinked NeMo config or checkpoint aliases as executable findings
- honor descriptor-owned header aliases during helper scanner selection for renamed HDF5, GGML, and compressed payloads
- detect signature-valid Torch7 payloads even when renamed with misleading suffixes
- detect acquired executable Llamafile payloads with misleading suffixes, retain archive-polyglot coverage, and classify unavailable runtime previews as inconclusive
- preserve Torch7 Lua findings in executable Llamafile/Torch7 polyglot payloads
Performance Improvements
- reuse source-validated pickle call-graph analysis across multiple directory dispatches when supported by installed picklescan
0.2.45 (2026-05-03)
Bug Fixes
0.2.44 (2026-05-03)
Bug Fixes
- address ai quality findings (#1218) (30f4ef2)
- clear remaining security-quality findings (#1219) (259f931)
Performance Improvements
- add opt-in core phase timings (#1170) (75a7f0b)
- bound directory progress pre-counts (#1174) (23dc5d0)
- bound ordinary license header reads (#1197) (113ad34)
- cache call graph call nodes (#1215) (aa52759)
- cache function import aliases (#1214) (d56eef2)
- cache manifest trusted-url lookups (#1186) (09e76cf)
- cache parameter controlled names (#1213) (41b8f45)
- cache scanner selection policies (#1177) (371f480)
- cache split call graph names (#1212) (77ab177)
- dedupe repeated metadata urls (#1166) (b3f1009)
- reuse cache key content hash on store (#1171) (e3981bd)
- reuse call graph controlled names (#1198) (84e6a9b)
- reuse call graph module parses (#1167) (0822b40)
- reuse compiled pmml extension patterns (#1172) (51ddc85)
- reuse default secret regexes (#1185) (b5ba149)
- reuse flax layer keyword text (#1187) (b50947f)
- reuse flax structure analysis (#1188) (c33c566)
- reuse flax suspicious patterns (#1194) (0351de1)
- reuse hashes for hardlinked files (#1175) (aac4367)
- reuse jax probe file handle (#1161) (3e95649)
- reuse jinja scanner patterns (#1184) (bb5a729)
- reuse jit import regexes (#1190) (9f37f5d)
- reuse lowered blacklist payload (#1165) (624a17b)
- reuse lowered c2 payload scan (#1163) (a63efaa)
- reuse lowered flax transform values (#1169) (3d73ad7)
- reuse lowered get_file values (#1211) (3bc7890)
- reuse lowered hex token seed checks (#1202) (8a34db9)
- reuse lowered jax context text (#1164) (d012c09)
- reuse lowered keras metadata text (#1168) (abfe87b)
- reuse lowered layer type names (#1203) (4b94a67)
- reuse lowered license header text (#1162) (447ea66)
- reuse lowered metadata filenames (#1205) (4251df5)
- reuse lowered metadata keys (#1206) (3ea11f0)
- reuse lowered ml operation names (#1201) (c5de398)
- reuse lowered sarif messages (#1209) (fde43a4)
- reuse lowered secret descriptions (#1208) (cb0324b)
- reuse lowered skops member names (#1207) (879c531)
- reuse lowered xgboost legacy headers (#1204) (8bc1e7d)
- reuse manifest text within scans (#1160) (848bc1e)
- reuse metagraph attr lowercase values (#1200) (349751e)
- reuse nearby license discovery (#1155) (301618d)
- reuse network library patterns (#1191) (630bd3d)
- reuse normalized scanner selection policy (#1153) (b8430a0)
- reuse onnx model bytes for parsing (#1193) (a5356a5)
- reuse prefiltered sarif issues (#1210) (d996043)
- reuse savedmodel function patterns (#1183) (c043bcd)
- reuse secrets detector heuristics (#1189) (799e8bf)
- reuse sibling license directory listings (#1157) (5ec7f21)
- reuse suspicious port names (#1192) (8ed7665)
- share call graph caches within reports (#1156) (b16d37c)
- share getattr assignment candidates (#1199) (5d12903)
- short-circuit hf bookkeeping checks (#1154) (ed0122d)
- skip call graph enrichment in pickle validation (#1196) (2347d80)
- skip directory pre-count without progress (#1173) (83c8bb4)
- skip redundant jax scans for plain pickles (#1158) (04c6974)
- skip renormalizing scanner selection (#1181) (74ac7a7)
- summarize CLI progress tree once (#1182) (0bc373f)
Documentation
0.2.43 (2026-05-01)
Bug Fixes
- align manifest scanner routing (#1111) (ad7f253)
- analyze jax-like pickle checkpoints (#1114) (576ac54)
- avoid inert skops cve false positives (7538e58)
- avoid PMML system substring false positives (#1125) (20fdd0c)
- catch suspicious nemo target leaves (#1116) (b8dccfa)
- close pytorch zip coverage gaps (#1095) (a1ca298)
- correct analysis suspiciousness (#1101) (11b1d3e)
- cover eager statistics consumers in picklescan (#1148) (0d5ea8e)
- detect bare torch7 require loads (#1117) (7c77be0)
- detect extensionless archive executables (#1110) (b64a2da)
- detect nested brace-format mapping lookups (#1151) (fc296ad)
- detect Paddle patterns across chunk boundaries (#1120) (d4fedf9)
- fail closed on bounded scanner analysis (#1099) (60973e4)
- fail closed on call graph errors (#1143) (1a08449)
- fail closed on directory size limits (#1093) (47054d7)
- fail closed on header-only streaming scans (#1103) (7b934c0)
- fail closed on incomplete mar scans (#1096) (af31235)
- fail closed on limited llamafile payload scans (ceb3f22)
- fail closed on malformed XGBoost JSON (#1123) (4d4ba28)
- fail closed on nemo archives without config (#1115) (a09f763)
- fail closed on ONNX raw detector failures (#1119) (2963764)
- fail closed on truncated tensor metadata (b267328)
- fail closed on unanalyzable call graphs (#1108) (dcb8bbe)
- fail closed when recognized scanners are unavailable (#1104) (f4866d4)
- fail closed without yaml parser (99ef15a)
- harden detector heuristics (#1100) (bf57b3b)
- ignore inert format placeholders (#1142) (8f728e8)
- ignore inert XGBoost feature labels (f637e1e)
- inspect savedmodel root siblings (#1118) (cf6bf8f)
- keep inert dotted global metadata clean (#1150) (9a76915)
- picklescan: detect hidden-only pytorch zips (#1098) (3e94f70)
- picklescan: detect statistics quantiles iterator consumption (#1152) (b357fdb)
- picklescan: fail closed on late encoded payload probes (#1107) (55b43a5)
- picklescan: model str.format lookups (#1097) (2c87acb)
- preserve exact entropy literals (#1138) (95ba57c)
- preserve hidden model payloads (#1091) (5b11f91)
- preserve incomplete office zip scans (#1094) (9ed81db)
- preserve merged scan failures (#1092) (e7fecc5)
- preserve path-sensitive directory scans (#1102) (ddebc52)
- preserve str.format lookup keys in picklescan (#1149) (feb3e1c)
- reject ajax as a JAX checkpoint hint (#1124) (9f51b2c)
- reject marker-only XGBoost binaries (#1122) (30ec930)
- remove filename-based framework skips (#1137) (7a18b49)
- require startup hook invocations (#1140) (7e0777d)
- require strict zip signatures (93f60af)
- resolve concatenated archive getattr names (#1105) (59a7df6)
- resync post-budget pickle replay (#1141) (e275676)
- route extensionless scanners (18accbd)
- route flax suffixes without msgpack (dca6056)
- route middle-marker llamafiles (f11792c)
- route renamed XML models after long prologs (#1109) (e2f9962)
- scan concatenated compressed members (#1135) (3f9a51a)
- scan embedded manifest chat templates (#1112) (18433a8)
- scan gguf chat templates with jinja analysis (#1113) (35b420a)
- scan unmarked python jit blobs (#1136) (681ce62)
- scope huggingface bookkeeping skips (#1090) (87f7204)
- stabilize non-pytorch zip status (7449aae)
- validate all XGBoost trees (#1121) (a38eab2)
Documentation
Bug Fixes
- detect nested brace-format lookups that reach tracked
defaultdictfactories - avoid
str.formatpicklescan false positives when aChainMapshadows adefaultdict - block
statistics.quantilescall-iterator consumption in picklescan call-graph analysis - block additional eager
statisticsconsumers in picklescan call-graph analysis - avoid picklescan false positives for inert metadata under dangerous dotted globals
- preserve path-sensitive scan results while hashing duplicate directory contents
- correct analysis suspiciousness scoring and alias-aware semantic risk handling
- harden detector heuristics against comment padding, byte-backed credentials, unmarked Python blobs, and spoofed network context
- fail closed when bounded scanner windows leave relevant model content uninspected
- fail closed when TorchServe MAR limits leave manifest-referenced payloads unscanned
- recurse into nested ZIP members inside PyTorch archives and fail closed when compression-ratio guards leave members unscanned
- preserve large Office-like ZIPs when prefilter inspection is incomplete
- fail closed when directory scans stop at the total-size budget
- restrict Hugging Face bookkeeping filename skips to recognized cache layouts
- preserve unsuccessful child results after scan-result merges
- preserve supported payloads hidden behind default directory-skip names
- use bounded raw Jinja fallback windows and fail closed when PyYAML is unavailable for YAML template configs
- let extensionless file scanners participate in local file selection so supported extensionless Llamafiles do not fall through to clean unknown results
- fail closed when PyTorch ZIP tensor-metadata validation can only inspect a bounded pickle prefix or cannot complete member analysis
- preserve and scan concatenated compressed-wrapper member boundaries so a benign first member cannot hide later malicious payloads
0.2.42 (2026-04-27)
Bug Fixes
- require latest picklescan release (a0237a7)
0.2.41 (2026-04-27)
Bug Fixes
- ci: skip POSIX proof cases on Windows (#1072) (bfa17a3)
- docker: add apt-get clean and pinned pip constraints to Dockerfile.tensorflow (#1079) (8d9f9b7)
- harden picklescan call graph RCE detection (#1061) (19c4fc4)
- harden picklescan stdlib callable detection (f0f57b4)
- improve test isolation, reduce duplication, and fix command injection risk in test suite (#1078) (3867c83)
- picklescan: avoid call-graph false positives for PyTorch storage IDs (#1069) (e75ed24)
- silence stale CodeQL generated import alerts (#1080) (9530740)
- telemetry: stabilize modelaudit identity (#1071) (592a656)
Documentation
0.2.40 (2026-04-17)
Bug Fixes
- add manual release recovery path (aeea2da)
- avoid duplicate manylinux compatibility tag (412677f)
- persist manylinux picklescan artifacts (346bb3f)
0.2.39 (2026-04-17)
Bug Fixes
0.2.38 (2026-04-17)
Features
Bug Fixes
- address code quality findings (#1038) (7af03cf)
- avoid per-call rule mapper closures (fa0dc70)
- bound pytorch zip jit reads (#1048) (f920d76)
- define analysis lazy exports (8aeeadd)
- deps: update rust crate pyo3 to 0.28.0 (#1006) (fe93b47)
- detect hidden pytorch zip pickles (#1043) (19b6ebe)
- detect proto0 pickles in 7z probes (c1fb7d6)
- enforce ZIP aggregate size budget (#1022) (94d576f)
- fail closed on incomplete ONNX weight analysis (#1025) (03413c5)
- fail closed on incomplete XGBoost analysis (#1019) (b8f334e)
- fail closed on oversized Skops entries (#1018) (3d74ab0)
- fail closed on pytorch zip timeouts (bf72f62)
- fail closed on RAR archives (#1030) (14b6e8f)
- fail closed on template truncation (#1026) (3d7967d)
- fail closed on unclassified scan failures (#1014) (dfe0455)
- harden incomplete Keras scanner paths (#1020) (86e017a)
- harden NeMo Hydra deserialization targets (#1021) (0f899a6)
- harden pickle nested bypass detection (#1027) (c3a3b9d)
- harden PyTorch pickle import classification (#1015) (7b00e55)
- harden remote cache and scanner bounds (#1031) (74c2b6d)
- preserve active payload severities (#1046) (13752e9)
- preserve scannable skipped ZIP containers (#1028) (29747d5)
- redact telemetry issue fields (#1023) (cd80d22)
- restore nested pickle CI coverage (b7a4846)
- route disguised nested archives in sevenzip scans (#1017) (cb2572e)
- route ONNX pb files by content (#1029) (6e9aa45)
- route PyTorch ZIP archives without metadata (#1016) (1f56bb8)
- route UBJSON-format .bst files to UBJ scanner (#1037) (52f869a)
- rule-mapper: preserve unknown opcode fallback (5153d68)
- run full Docker image as non-root (#1024) (c1d2be6)
- scan generic archive python handlers (#1047) (5b90a84)
Performance Improvements
Documentation
- align markdown with current repo state (#1035) (690bc52)
- align README support and dependency guidance (#1008) (5dcd62b)
- clarify security report closure policy (#1049) (d53e445)
- prune stale planning artifacts (#1010) (851cc10)
Added
- security: inspect non-canonical SavedModel root siblings for suspicious executable-like content
- security: detect bare-string Lua
require "module"loads in Torch7 artifacts - security: keep trusted NeMo namespaces from suppressing suspicious Hydra
_target_leaf names - security: fail closed when NeMo archives contain no analyzable config files
- security: analyze GGUF-embedded chat templates through the Jinja scanner while preserving GGUF scanner ownership
- security: run JAX checkpoint analysis for JAX-like pickle payloads that stay on the primary pickle scanner path
- security: detect
mailcap.findmatchpickle call targets that can execute attacker-controlled mailcaptestcommands on Python versions that still providemailcap - security: detect
setuptools._distutils.spawn.spawnpickle call targets that can execute attacker-controlled subprocess command lists whensetuptoolsis installed - security: detect
pipes.Templatepickle call targets that can execute attacker-controlled shell pipelines on Python versions that still providepipes - security: resolve module-level bound-method aliases and same-module constructor call paths in pickle call-graph analysis so process-dispatch wrappers are blocked
- security: resolve dangerous
six.movescompatibility aliases, including vendoredsixcopies, in pickle call-graph analysis so subprocess, pickle deserializer, and builtin execution wrappers are blocked - security: resolve constructor-default sink aliases assigned to instance attributes in pickle call-graph analysis so wrappers like Botocore credential process providers are blocked
- security: resolve sink defaults forwarded through
super().__init__in pickle call-graph analysis so async credential process wrappers are blocked - security: resolve parameter-fed function-local class instance aliases in
pickle call-graph analysis so wrapper functions like
click.editare blocked - security: resolve function-local import aliases in pickle call-graph analysis so wrappers that import RCE sinks inside function bodies are blocked
- security: preserve callable invocation aliases when import-reference metadata is crowded, while ignoring uninvoked nested function and lambda bodies during pickle call-graph analysis
- security: detect
typing._eval_typepickle call targets that can evaluate attacker-controlledForwardRefexpressions - security: detect
dataclasses._create_fnpickle call targets that can execute attacker-controlled generated Python source - security: detect
typing.get_type_hintspickle call targets that can evaluate attacker-controlled annotation strings - security: detect public
operator.callpickle call targets that can invoke attacker-controlled callables - security: detect
builtins.mappickle call targets that can lazily invoke attacker-controlled callables when iterated - security: detect
itertools.starmappickle call targets that can lazily invoke attacker-controlled callables when iterated - security: detect
builtins.filterpickle call targets that can lazily invoke attacker-controlled callables when iterated - security: detect
types.MethodTypepickle call targets that can synthesize attacker-controlled bound methods for later invocation - security: detect
types.DynamicClassAttribute.__get__pickle call targets that can invoke attacker-controlled descriptor getters - security: detect
functools.cached_property.__get__pickle call targets that can invoke attacker-controlled cached-property getters - security: detect
functools.cmp_to_keypickle call targets that can invoke attacker-controlled comparators during rich comparison - security: detect
logging.Filterer.filterpickle call targets that can invoke attacker-controlled logging filter callbacks - security: detect
inspect.getmemberspickle call targets that can invoke attacker-controlled descriptors during introspection - security: detect
builtins.hasattrpickle call targets that can invoke attacker-controlled descriptors during attribute-existence checks - security: detect
__del__finalizer string seeds that can execute attacker-controlled methods when pickle-built objects are dropped - security: detect
__eq__rich-comparison string seeds that can execute attacker-controlled methods during equality checks - security: detect
__lt__,__le__,__gt__,__ge__, and__ne__rich-comparison string seeds that can execute attacker-controlled methods during ordering checks - security: detect
__contains__membership string seeds that can execute attacker-controlled methods during containment checks - security: detect
__setitem__item-assignment string seeds that can execute attacker-controlled methods during item mutation - security: detect
__getitem__and__delitem__item-protocol string seeds that can execute attacker-controlled methods during item access - security: detect binary arithmetic and bitwise dunder string seeds that can execute attacker-controlled methods during operator dispatch
- security: detect reflected and in-place binary operator dunder string seeds that can execute attacker-controlled methods during operator dispatch
- security: detect unary operator dunder string seeds that can execute attacker-controlled methods during operator dispatch
- security: detect context-manager entry dunder string seeds and
contextlib.ExitStack.enter_contextpickle call targets that can invoke attacker-controlled__enter__methods - security: detect iteration protocol dunder string seeds that can execute attacker-controlled methods during builtin iteration dispatch
- security: detect numeric rounding protocol dunder string seeds that can execute attacker-controlled methods during rounding helper dispatch
- security: detect descriptor setup and numeric coercion dunder string seeds that can execute attacker-controlled methods during class creation
- security: detect presentation and size protocol dunder string seeds that can execute attacker-controlled methods during common builtin dispatch
- security: detect PathLike
__fspath__dunder string seeds that can route attacker-controlled paths into file APIs during pickle loading - security: detect direct pickle calls to stdlib file-write sinks such as
pathlib.Path.write_text,io.open, and_io.FileIO - security: detect pickle calls to logging file handlers and emit/handle dispatch methods that can write attacker-controlled startup hooks
- security: detect pickle calls to
argparse.FileTypeand high-level logging stream dispatch methods that can write attacker-controlled startup hooks - security: detect pickle calls to NumPy text writers that can write attacker-controlled startup hooks
- security: detect pickle calls to
python-dotenvkey writers that can write attacker-controlled startup hooks - security: detect pickle globals whose Python call graph reaches known
RCE-capable source primitives such as
os.execvpe - security: detect pickle globals whose Python call graph pairs file-open and file-write wrappers that can create executable startup hooks
- security: resolve pickle-imported Python class globals through bounded constructor and object-method call graph entrypoints
- security: detect public
io.FileIOandio.TextIOWrapper.writealiases for blocked_iofile-writing primitives - security: detect builtin namespace dictionary access that can recover blocked primitives through mapping lookups
- security: detect dotted pickle global aliases that resolve to blocked
source primitives such as
os.system - security: detect concrete
pathlibpath writer aliases and module namespace dictionary recovery for modules with blocked globals - security: detect module namespace and
__builtins__access used for dynamic builtin recovery - security: detect
string.Formatter.get_fieldpickle call targets that can traverse attacker-controlled field expressions into callable objects - security: detect
unittest.mock._get_targetpickle call targets that can manufacture delayedpkgutil.resolve_nameresolver partials - security: detect descriptor getter pickle call targets that can bind recovered function descriptors and expose builtin namespaces
- security: detect wrapper and method descriptor getter pickle call targets that can bind recovered slot wrappers for dynamic attribute access
- security: detect global references to attribute-access and function namespace source methods used for dynamic builtin recovery
- security: detect object subclass enumeration globals that can recover loaded process capabilities without direct imports
- security: detect garbage collector object-graph globals that can recover hidden namespaces and loaded process capabilities
- security: detect frame-introspection globals and frame namespace descriptor getters used for dynamic builtin recovery
- security: detect callable
__call__aliases of blocked pickle globals used to invoke hidden RCE source primitives - security: detect wrapper
__get__and__self__aliases of blocked pickle globals used to recover hidden RCE source primitives - security: detect attribute aliases under blocked pickle global prefixes used to recover hidden RCE source primitives
- security: detect pickle calls to PyYAML unsafe loaders that can execute attacker-controlled Python constructors
- security: detect pickle calls to
codecs.openand codec stream writes that can write attacker-controlled startup hooks - security: detect pickle calls to durable tempfile creation and CSV
DictWriterrow dispatch that can write attacker-controlled startup hooks - security: detect pickle calls to mailbox single-file
adddispatch methods that can write attacker-controlled startup hooks - security: detect pickle calls to
_tkinterTcl interpreter dispatch methods that can execute local commands - security: detect high-level
tkinter.Miscpickle call targets that can forward attacker-controlled commands into Tcl interpreter dispatch - security: detect pickle calls to
_xxsubinterpreters.run_stringthat can execute attacker-controlled Python source - security: detect
builtins.staticmethodpickle call targets that can synthesize callable descriptors for later invocation - security: detect
builtins.property.__get__pickle call targets that can invoke attacker-controlled property getters during descriptor access - security: detect
builtins.classmethod.__get__pickle call targets that can synthesize attacker-controlled bound methods during descriptor access - security: detect
_functools.partialpickle call targets that can synthesize private-alias partial callables for later invocation - security: detect
_functools.reducepickle call targets that can invoke attacker-controlled reducer callables through the private CPython alias - security: detect
functools.cache,functools.lru_cache, andfunctools.singledispatchpickle call targets that can synthesize callable wrappers around attacker-controlled functions for later invocation - cli: add scanner selection with
--scanners,--exclude-scanner, and--list-scannerswired into core routing, nested dispatch, remote prefilters, and scan metadata; selection-suppressed preferred scanners emit a stderr warning and populatescanner_selection.suppressed_preferred_scanner_ids, and unknown scanner names suggest the closest match - pickle: replace the standalone pickle scanner's package-engine selector with the Rust-only runtime and explicit native-extension errors
- pickle: scan PyTorch ZIP checkpoint pickle members directly in the standalone pickle scanner
- pickle: bundle the standalone
modelaudit_picklescanAPI in the rootmodelauditwheel and add source-tree coverage for the package boundary - tests: enable existing PaddlePaddle scanner tests in CI by adding
test_paddle_scanner.pyto the allowed test files list (Python 3.10/3.12/3.13) - security: detect CVE-2026-1669 Keras HDF5 external weight references in standalone
.h5and embedded.kerasweights - security: detect CVE-2026-24747 PyTorch weights_only=True bypass via SETITEM/SETITEMS abuse and tensor metadata mismatch detection
- security: detect CVE-2022-45907 PyTorch torch.jit.annotations.parse_type_line unsafe eval() injection (CVSS 9.8)
- keras: detect CVE-2025-12058 StringLookup external vocabulary path loading in
.kerasconfigs (local file read / SSRF)
Changed
- telemetry: persist ModelAudit distinct IDs in Promptfoo's global config
format (creating
~/.promptfoo/promptfoo.yamlif absent and migrating any legacy~/.modelaudit/user_config.jsonID) and includeisRunningInCion analytics payloads, with presence-based detection for marker-style providers (TeamCity, CodeBuild, Bitbucket, Jenkins) - docs: align public README and compatibility guidance with supported Python 3.10-3.13, TensorFlow extra requirements, supported formats, and telemetry sanitization behavior
- security: credit @mosebit for privately reporting a TensorRT native-code detection gap that helped harden native-code scanner coverage
- security-policy: clarify when low-impact scanner coverage gaps may be closed without publishing a public advisory while still crediting reporters
- pickle: increase Rust stream read chunks to reduce scan overhead on large file and archive-member inputs
- pickle: store Rust byte stack operands as source spans instead of copied previews to reduce large-pickle scan overhead
- pickle: skip no-seed raw-text and CVE fallback passes on clean Rust-complete pickle scans, tightening benign state-dict CLI performance while preserving targeted raw-detector positives
- pickle: document and pin parse-incomplete tail suppression to trusted pickle boundaries without dangerous import references; parse failures with security findings or dangerous imports still fail closed
- security: bump the optional ONNX dependency to
1.21.0rc3, which removes the vulnerableonnx.hubmodule flagged by CVE-2026-28500.
Rule Codes
- pickle: preserve and document Rust pickle scanner mappings for SETITEM abuse (
S209), copyreg extensions (S211), persistent IDs (S212), nested or encoded pickle payloads (S213), base64/hex/obfuscated encoded payloads (S601/S602/S604), structural tamper and incomplete analysis (S902), and the new pickle expansion denial-of-service rule (S214). - pickle: keep internal Rust finding codes such as
STRUCTURAL_TAMPERandPICKLE_EXPANSIONinpickle_rule_codedetails while exposing stable ModelAudit rule codes for dashboards, SARIF, suppression, and severity configuration.
Fixed
- llamafile: stream marker detection across executable bodies so
.exewrappers with middle-onlyllamafilemarkers still route to the scanner - flax: keep explicit Flax/JAX checkpoint suffixes routed to the scanner when
msgpackis unavailable so missing parser coverage fails closed - llamafile: fail closed when bounded embedded-payload scanning stops before covering the full executable
- skops: require exploit-shaped structured loader nodes for CVE-2025-54412 and CVE-2025-54413 checks so inert prose, filenames, and valid loader nodes do not become critical findings
- routing: require recognized ZIP signatures before classifying files or
streaming previews as archives, so benign
PK*near-matches stay unclassified - xgboost: avoid flagging inert
feature_namesmetadata as executable JSON content. - pmml: avoid flagging benign
ecosystem()prose as asystem(...)call. - jax: avoid routing
ajaxnear-matches as JAX checkpoint indicators. - security: fail closed on malformed nested XGBoost JSON structures that would otherwise skip booster or tree validation.
- security: require the legacy XGBoost binary signature instead of
accepting marker-shaped text payloads as valid
.bstmodels. - security: validate late XGBoost trees instead of sampling only the first ten tree structures.
- security: detect PaddlePaddle suspicious tokens that span the scanner's 1 MiB read boundaries.
- routing: align manifest scanner routing with the manifest filenames and dedicated manifest-style suffixes declared by the registry.
- security: detect strong executable headers in generic archive members even when the payload has no executable-looking suffix.
- routing: preserve renamed OpenVINO and PMML XML models with long benign prologs during content-based directory filtering.
- security: resolve compile-time string concatenation in archive-member
getattrcalls so high-risk targets likeos.systemcannot hide behind split literals - security: fail closed when routing recognizes a model format but no scanner is available to analyze it
- security: fail closed when streaming scans only fall back to heuristic header checks, even if the remote file bytes were fully read
- docs: narrow public scan-coverage wording so unsupported or merely discovered formats are not over-promised
- analysis: keep exact dangerous literals visible even when surrounding bytes look like ML weights
- analysis: stop attacker-controlled file and directory names from suppressing dangerous framework-pattern findings
- security: detect dangerous marker-free Python source blobs through the public JIT path so disguised archive members are still analyzed
- security: mark ONNX scans inconclusive when raw JIT/script or network detector analysis cannot complete instead of treating detector failures as clean passes.
- security: run Jinja template analysis for manifest-owned configs that carry embedded chat-template fields.
- pickle: detect stdlib filesystem probe and process-state callables such as
pathlibmetadata methods,decimal.setcontext, andgc.disableduring pickle scans, while keeping local container mutations clean and covering publicoperator.setitemregistry poisoning plus target-awareoperator.imulwarning-filter mutation. - pickle: detect public
operator.setitempickle calls, keep callable invocation aliases ahead of import-reference budget exhaustion, dedupe repeated invocation metadata before the reporting cap, preserve literal mapping-key shadowing throughChainMap, block deeply wrappeddefaultdictfactories, and avoid outer-function call-graph false positives from nested function and lambda bodies. - security: prevent HuggingFace whitelist provenance from downgrading active payload, CVE, traversal, executable, operational-error, or incomplete-coverage findings. Exemptions now cover S1xx code-execution primitives (
S101–S115) and HIGH-severity S3xx network primitives (S301/S304/S305/S310), and the keyword fallback uses word-boundary matching so substrings like "executable" inside "ExecuTorch" no longer over-suppress legitimate downgrades. - security: scan generic ZIP/TAR/NPZ Python members and ZIP/TAR/NPZ executable members, including wildcard imports and callable rebindings while failing closed on malformed Python source. Findings carry accurate rule codes per risk category (
S101foros.system/os.popen,S103forsubprocess.*,S104foreval/exec,S106for__import__,S107forimportlib.import_module,S213forpickle.load/pickle.loads) instead of a single catch-all, the ZIP path now honorsmax_mar_python_analysis_bytesfor non-MAR Python members, and source bytes are parsed directly so PEP 263 encoding declarations are respected. - security: bound PyTorch ZIP JIT/network member reads (default 32 MiB per-member cap, configurable via
max_jit_scan_member_bytes) and mark oversized or unreadable member coverage inconclusive. Oversize and read-failure events are aggregated into a single summary INFO check per kind (with per-member detail indetails["entries"]) so adversarial archives cannot flood the checks list, duplicate-name entries are de-duplicated byZipInfoidentity rather than filename so the second of two same-name members is still analyzed, directory entries are skipped explicitly, and pickle members continue through the bounded JIT/network pass so padded payloads remain covered beyond the pickle scanner raw window. - security: detect hidden PyTorch ZIP pickle members even when a benign
data.pklis already present. The bounded-prefix sniff now always runs across unselected members (including extensionless payloads and files underdata/<n>), fails closed with one aggregated INFO check if probe reads raise (was one check per failed member), and is mirrored in the standalonemodelaudit-picklescanpackage so both code paths discover the same hidden payloads. - security: mark PyTorch ZIP scan timeouts inconclusive and unsuccessful instead of reporting complete coverage.
- security: detect extensionless protocol-0/1 pickle members during 7-Zip nested archive probes.
- pickle: restore ModelAudit nested-pickle findings from Rust standalone notices and keep network raw-detector coverage after native pickle findings
- xgboost: route UBJSON-backed
.bstmodels whenversionor booster markers appear after a largelearnerobject, and route extensionless XGBoost UBJSON models via content sniffing (requires both thelearnermarker and a booster/model-param strong marker within the probe window). - telemetry: strip query strings, fragments, and URL userinfo from cloud model names and file-extension metadata
- preserve
S999unknown-opcode mapping in generic rule fallback - docker: run the full parser image as a non-root
appuser - onnx: mark weight-distribution analysis inconclusive when dependencies are missing or eligible tensors are external, oversized, or fail extraction
- zip: enforce an aggregate uncompressed-size budget before extracting ZIP entries so split archive bombs cannot bypass per-entry limits
- security: flag NeMo Hydra
_target_values that invoke ML deserialization loaders such astorch.load,joblib.load, Keras load-model APIs, and related pickle-backed helpers. - telemetry: replace free-form issue messages in telemetry issue fields with stable rule/CVE/type identifiers
- security: route renamed TFLite FlatBuffers by magic bytes, enforce scanner file-size limits before model reads, and fail closed instead of propagating malformed structure traversal exceptions
- onnx: fail closed on CRITICAL findings, detect
PyFuncoperators and Windows absolute external-data paths, validate external tensor slices with the current ONNX dtype API, and avoid Python-op substring false positives - tensorrt: route
.trtengines, detect case-variant and UTF-16 suspicious strings, and avoid substring false positives in benign engine metadata - coreml: detect Python 3 command metadata, Windows and bundle-macro linked-model escapes, malformed custom-code protobuf blocks, and custom layers nested under pipeline wrappers while preserving safe-key metadata URL inspection
- pmml: enforce max-file-size limits, inspect namespaced Extension/script tags, ignore DOCTYPE/ENTITY text inside XML comments/CDATA, avoid recursive text-walk crashes on deeply nested Extension trees, and fail closed when CRITICAL PMML findings are present
- gguf: fall back to the GGUF spec default tensor-data alignment after rejecting invalid
general.alignmentmetadata values - security: detect protocol 0/1 pickle streams hidden behind long separator gaps after an initial safe pickle stream
- security: preserve failed status for malicious Skops CVE detections and avoid CVE-2025-54886 false positives on benign README/model-card text such as "download"
- security: validate HuggingFace repo path components before cache path construction, revalidate HuggingFace cache freshness through the provider SDK, bound XGBoost JSON routing sniffing, redact signed cloud URLs from cache metadata, and default full-file scanner reads to bounded fail-closed limits
- security: enforce Flax msgpack scanner file-size limits before full reads, scan trailing msgpack stream objects with a bounded object-count cap, downgrade benign container-like trailing-object findings to INFO, and preserve failed status when CRITICAL findings are reported
- security: route
.joblibfiles through the Joblib scanner, scan raw protocol-0/1 payloads directly, support gzip/bzip2/lzma/zlib wrappers with bounded output and trailing-data checks, preserve embedded Pickle finding locations, and fail closed on undecodable/trailing-wrapper errors - security: route ONNX protobuf payloads saved with a
.pbsuffix by content before TensorFlow protobuf extension fallback - security: detect direct
getattr(module, "dangerous")handler calls in TorchServe MAR archives, parse conflicting duplicate manifests without silently downgrading hidden handlers, and suppress collision warnings for byte-identical duplicate manifests - security: recognize RAR archives and fail closed as unsupported coverage instead of skipping
.rarfiles during directory scans - skops: fail closed when Skops archive limits, malformed archives, or bounded metadata reads leave CVE coverage incomplete, while preserving benign numeric-array payload scans
- xgboost: fail closed on incomplete JSON, UBJ, binary-structure, pickle-spoof, and enabled-loader analyses while preserving core exit-code and cache semantics
- security: route disguised ZIP and TAR members inside 7-Zip archives by bounded header probes while stopping probe reads at the per-member budget
- security: reduce NeMo Hydra
_target_false positives by matching suspicious identifiers on token boundaries, preserve CVE-2025-23304 details on suspicious-target findings, and reject oversized YAML members before parsing - security: preserve skipped-suffix ZIP containers when Keras config-only structure or embedded model-like
.binmembers indicate scannable content - security: fail closed when oversized NeMo YAML prevents Hydra target analysis and scan malformed Jinja2 config fallbacks beyond the initial prefix window
- security: detect protocol 0/1 pickle streams with trivial opcode prefixes even when
STOPis followed by trailing junk, while preserving plain-text near-match rejection - security: detect protocol 0/1 pickle streams whose dangerous opcode appears after large trivial padding or after a non-trivial probe-boundary prelude, reject all-trivial no-
STOPprobe prefixes, and preserve rule codes across cached scan-result round trips - pickle: propagate standalone fallback parse and stream-read failures into merged scan success, preserve truncated
.binfail-closed behavior, reuse non-seekable stream spools for the legacy parity pass, clamp negative stream sizes, and reset post-budget scan state between reused scanner runs - pickle: align Rust pickle suspicious-string matching, protocol-0 text decoding, EOF-before-
STOPhandling, malformed argument diagnostics, parse-incomplete reports, warning dangerous-call adaptation, negative stream sizes, and compatibility finding promotion with Python parity - pickle: harden Rust opcode parity for protocol 5 buffers, copyreg extensions, follow-on streams, protocol-0 encoded nested payloads, and
__main__call escalation while bounding Python raw-detector hot paths - pickle: preserve root raw-detector coverage for Slack tokens,
mongodb+srv://secrets, bare IPs, domains, and network-library/function indicators behind large-file compatibility prefilters - pickle: detect modern
STACK_GLOBAL,INST, and copyreg extension references in post-budget pickle tails, avoid a second Rust-boundary copy of Python byte payloads, and skip expensive raw detectors for realistic benign PyTorch state-dict key streams - pickle: route crafted protocol-1 binary pickle headers and nested protocol-1 payload prefixes through the same scanner paths as newer binary protocols
- pickle: enforce PyTorch ZIP entry limits with a bounded EOCD preflight before opening over-cap archives
- pickle: resolve memoized
GET/BINGET/LONG_BINGEToperands in post-budgetSTACK_GLOBALtails so pre-memoized dangerous globals cannot bypass the Rust scanner - pickle: detect no-
PROTObinary-opcode nested payloads in raw/base64/hex fields, fail closed when nested probe candidates exceed the bounded budget, and flag process-termination/resource primitives such asbuiltins.exit,faulthandler._sigsegv, andresource.setrlimit - numpy: propagate incomplete embedded-pickle scan status from object-dtype
.npypayloads so partial recursive pickle coverage fails closed - license: bound binary header scans and reuse compiled patterns to avoid full-file regex passes on large model archives
- security: stop iterating malformed TFLite models after excessive subgraph counts are detected
- openvino: route forbidden-DOCTYPE IR XML into the OpenVINO scanner, fail closed on XML parse errors, and suppress warning-level format-validation noise for benign
.xmlmodels with no distinctive magic bytes - security: fail closed on conflicting duplicate or alias Keras root members so benign trailing
config.jsonentries cannot hide malicious earlier configs, while accepting byte-identical duplicates without warning noise - security: detect PyTorch binary code and blacklist patterns that straddle chunk boundaries, avoid duplicate overlap reports, and return
success=Falsewhen CRITICAL findings are present - fail closed on bare scanner
success=Falseresults across object, dict, streaming, and cached scan paths instead of allowing clean aggregate success - security: harden PyTorch ZIP pickle import classification without downgrading dangerous builtins or known benign rebuild aliases
- security: scan every duplicate PyTorch ZIP member by physical archive entry and report conflicting duplicate names at INFO severity so benign trailing
data.pklentries cannot shadow malicious earlier payloads without making benign-but-conflicting duplicates warning-fail by themselves - security: route metadata-stripped PyTorch ZIP archives by numeric tensor storage members only, preserving generic ZIP routing for data-directory near-matches
- security: route misnamed Skops ZIPs by bounded schema sniffing, treat encrypted Skops-like schema members as non-matches instead of crashing routing, recurse into embedded members while preserving Skops-specific CVE checks, avoid tiny nested
.binfalse positives on clean archive members, preserve nested-member byte accounting, and preserve CLIscanner_namesin aggregated JSON output - pickle: bound post-budget global fallback state, retained findings, and deadline checks to prevent crafted pickle tails from exhausting scanner memory or flooding logs
- pickle: mark timeout-, budget-, recursion-, and resource-limited pickle scans as inconclusive so clean-looking partial analysis returns exit code 2 unless real security findings were reported
- route misnamed ZIP, HDF5, and 7z files through content-aware scanner selection
- security: recursively scan all members of content-routed
.kerasZIP archives with bounded per-member extraction, prefer canonical root members over normalized aliases, and fail closed on ambiguous duplicate aliases so embedded payloads and./config.jsonentries are not skipped - keras: fail closed when embedded
.kerasweights exceed inspection limits, constrain fully-qualified H5/ZIP Lambda CVE attribution to Keras/TensorFlow namespaces, and avoid CVE noise for documentation URLs that mentionget_file. - security: scan duplicate ZIP entries by physical archive member instead of resolving repeated names to the final entry, preventing shadowed payloads from being skipped during recursive archive analysis
- bound Keras
config.jsonandmetadata.jsonmember reads before JSON parsing - openvino: parse XML roots for long-prolog routing, enforce size limits before parsing, scan nested layer attributes for external library references, and avoid importlib substring false positives
- zip: propagate nested critical findings and incomplete archive traversal to
success=False, and bound symlink-target reads before path validation - tar: propagate nested critical findings and partial archive traversal to
success=False, continue after per-entry extraction errors, and normalize malformed archive-limit configs to safe defaults - route oversized config-only Keras ZIP archives by bounded config-prefix sniffing instead of falling back to the generic ZIP scanner
- preserve disguised model files during directory prefiltering without promoting document ZIPs
- fail closed on duplicate 7z entries, nested critical findings, probe-limit truncation, and malformed 7z safety-limit configs
- oci: fail closed on nested findings and partial layer traversal, content-sniff misnamed layer members, normalize cosmetic layer-ref suffix changes, and reject oversized members before temp extraction
- oci: ignore non-layer metadata strings ending in
.tar.gzwhen collecting manifest layer refs so benign URLs do not become false missing-layer failures - recurse into nested 7z members even when their filenames use misleading extensions
- fail closed on extreme-size files when a scanner lacks bounded large-file analysis
- harden scan-cache invalidation and skip caching operational scan failures
- propagate CLI cache settings into MLflow and JFrog downloads
- avoid materializing streaming directory iterators in memory
- fail closed when JFrog folder downloads return only partial results
- keras: anchor safe Lambda normalization regexes in H5 scanning so appended statements (for example
; __import__(...)) cannot bypass dangerous-code analysis - keras: harden Keras H5 scanning by propagating CRITICAL findings to
success=False, scanning wrapper-owned nested layers, parsing prerelease fix-boundary versions correctly, and matching suspicious module/config tokens without benign substring false positives - complete primary header-format routing in
core.pyso all registered model formats map to scanner IDs (including OpenVINO/PMML/CNTK/LightGBM/Torch7/CatBoost/RKNN/MXNet/NeMo/Llamafile/TFLite/CoreML/Paddle/TensorRT/Flax/R/ExecuTorch/7z/compressed/skops/joblib/xgboost/jax_checkpoint), add.skopsextension detection coverage without spurious ZIP mismatch noise, and route ZIP-backed PyTorch.ckpt/.pklcontainers through the PyTorch ZIP path - security: track pickle
BUILD-driven__setstate__mutation on non-safe globals and block tree-model opcode-threshold escalation when dangerous globals are present in-stream - safetensors: include BOOL, BF16, F8_E4M3, and F8_E5M2 dtypes in tensor-size validation so malformed offsets are no longer skipped
- harden pickle symbolic stack simulation by ignoring stack-neutral opcodes and using unknown sentinels for unhandled stack pushes
- security: scan TensorFlow SavedModel
assets/andassets.extra/directories for executable-like content (shebang scripts, ELF/Mach-O binaries, pickle magic, and embedded Python source patterns) - security: make TensorFlow SavedModel scans fail closed on CRITICAL findings, avoid substring false positives in PyFunc function references, and treat
blacklist_patterns=Noneas disabled instead of emitting DEBUG read errors - security: enforce SafeTensors
MAX_HEADER_BYTESduringscan()and skip regex-heavy metadata-content analysis when headers exceed the configured limit to reduce header-based DoS risk - emit a one-time warning when the HuggingFace whitelist snapshot is older than 90 days while preserving existing whitelist severity downgrades
- treat pickle scan timeouts as unsuccessful while preserving post-budget tail scans after opcode truncation
- harden pickle CVE-2026-24747 SETITEM detection against stack-neutral padding
- keras: harden CVE-2025-9906 detection against documentation-padding bypasses in
.kerasconfig.json - count successful
stream://scans infiles_scannedso clean streaming scans return exit code 0 instead of 2 - harden 7z nested archive scanning and pre-extraction size checks
- scan follow-on pickle streams after large padding blocks
- security: add a budget-independent post-truncation GLOBAL/INST/STACK_GLOBAL byte scan (100 MB capped) so dangerous imports hidden past opcode limits are still detected
- security: detect nested pickle payloads in BINBYTES8 and BYTEARRAY8 opcodes
- security: scan bounded sliding windows for padded nested pickles hidden beyond the first 1 KB in raw, legacy
BINSTRING, and base64/hex-encoded payloads - onnx: treat official
ai.onnx.mlandai.onnx.preview.trainingdomains as standard so only truly custom domains are flagged - reject local streaming symlink traversal outside the scan root
- require explicit remote Hugging Face provenance for whitelist downgrades
- preserve scannable archives, hidden model files, hidden DVC pointers, and local
.metadatafiles in directory scans - tighten Hugging Face cache-root matching so only real
.cache/huggingface/hublayouts get cache-specific filtering and provenance handling - preserve validated PE detections in pickle binary ML-context filtering
- security: fail closed on pickle opcode parse errors for
.pkl/.pickle/.joblib/.dillfiles instead of returning a successful INFO-only scan - security: surface an explicit INFO limitation when large pickle raw byte-pattern heuristics cover only the first 10 MB of the file
- security: preserve full scanner execution for large files when scanners do not implement chunk analyzers
- harden manifest URL trust checks and enforce metadata/manifest scan limits
- harden metadata scanner URL handling so shorteners/tunnels hidden in userinfo are flagged without treating ordinary authenticated URLs as suspicious
- trust legitimate AWS S3 virtual-hosted regional and legacy manifest URLs without broadening other
amazonaws.comhosts - treat all-uppercase pickle module segments as plausible imports
- recurse into extensionless nested ZIP members by content
- preserve mixed ZIP/TAR/MAR archive depth limits
- security: keep Hugging Face model downloads fail-closed when repo listing errors/timeouts prevent exact file allowlists, and run disk-space preflight against the default HF cache even without an explicit
cache_dir - security: bound embedded
.kerasweight extraction before temporary-file inspection to reduce zip-bomb denial-of-service risk - security: prevent ExecuTorch binary ZIP polyglots from bypassing archive scanning
- security: keep spoofed built-in Keras
registered_namevalues from hiding non-allowlisted custom modules in.kerasZIP scans - keras: suppress duplicate custom-object warnings for allowlisted registered objects when module metadata is absent
- security: analyze TorchServe MAR
requirements.txtfiles for supply-chain attack indicators such as non-PyPI indexes, editable/git installs, direct remote URL installs, external requirement includes, insecure HTTP URLs, remote find-links, and typosquatting package names while ignoring inline comments - security: stop auto-applying local
.modelaudit.tomlandpyproject.tomlrule config during scans unless a human explicitly trusts that config in an interactive scan; remembered trust is stored securely under the local ModelAudit cache and invalidated when the config changes - telemetry: preserve secret-scrubbed model references in telemetry payloads while omitting raw credentials, query strings, and local directory paths
- cli: preserve original local files during
--streamdirectory scans instead of unlinking them after analysis - security: reduce benign pickle scanner noise by suppressing placeholder
__reduce__findings, narrowing generic base64-like string heuristics, and applying default suppression for the JWT.io example token - security: recurse into object-dtype
.npypayloads and.npzobject members with the pickle scanner while preserving CVE-2019-6446 attribution and archive-member context - eliminate false positives for valid ExecuTorch FlatBuffers binaries and file-type validation on public
.ptemodels - eliminate Keras ZIP false positives for safe built-in and allowlisted serialized objects such as
AddandNotEqual - security: remove
dill.load/dill.loadsfrom the pickle safe-global allowlist so recursive dill deserializers stay flagged as dangerous loader entry points - security: add exact dangerous helper coverage for validated torch and NumPy refs such as
numpy.f2py.crackfortran.getlincoef,torch._dynamo.guards.GuardBuilder.get, andtorch.utils.collect_env.run - security: add exact dangerous-global coverage for
numpy.load,site.main,_io.FileIO,test.support.script_helper.assert_python_ok,_osx_support._read_output,_aix_support._read_cmd_output,_pyrepl.pager.pipe_pager,torch.serialization.load, andtorch._inductor.codecache.compile_file(9 PickleScan-only loader and execution primitives) - security: treat legacy
httplibpickle globals the same ashttp.client, including import-only andREDUCEfindings in standalone and archived payloads - security: detect import-only pickle
GLOBAL/STACK_GLOBALreferences while preserving safe constructors, legacy Python 2 aliases, keyword-onlyNEWOBJ_EXanalysis, and large native extension scans - security: fail closed on malformed
STACK_GLOBALoperands when memo lookups are missing or operand types are non-string, while keeping simple truncation-only context informational - security: remove
builtins.hasattr/__builtin__.hasattrfrom the pickle safe-global allowlist so attribute-access primitives stay flagged as dangerous builtins - security: harden pickle blocklist enforcement by removing
_pickle.Unpickler/_pickle.Picklerfrom safe globals, addingcopyreg.add_extension/copyreg.remove_extensionto suspicious globals, and limiting functools warning downgrades topartial/partialmethodsofunctools.reducefindings stay CRITICAL - security: harden TensorFlow weight extraction limits to bound actual tensor payload materialization, including malformed
tensor_contentand string-backed tensors, and continue scanning past oversizedConstnodes - security: stream TAR members to temp files under size limits instead of buffering whole entries in memory during scan
- security: inspect TensorFlow SavedModel function definitions when scanning for dangerous ops and protobuf string abuse, with function-aware finding locations
- security: route oversized TensorFlow MetaGraph files to fail-closed parse-budget scans, inspect
AttrValue.func.namereferences in executable ops, and restore oversized-attribute anomaly detection after bounded string decoding - cli: include streamed artifacts as SBOM components when
scan --stream --sbomis used - cli: exclude HuggingFace download cache bookkeeping files from remote SBOMs and asset lists
- cli: add
--no-whitelistand--strictwhitelist/caching hardening so CI scans can disable HF severity downgrades and force uncached analysis - security: require official or explicitly allowlisted JFrog hosts before treating
/artifactory/URLs as authenticated JFrog endpoints - security: detect CVE-2024-5480 PyTorch torch.distributed.rpc arbitrary function execution via PythonUDF (CVSS 10.0)
- security: detect CVE-2024-48063 PyTorch torch.distributed.rpc.RemoteModule deserialization RCE via pickle (CVSS 9.8)
- security: detect CVE-2019-6446 in NumPy scanner when object-dtype arrays are found, with informational attribution (CVSS 9.8) due to potential pickle deserialization via
allow_pickle=True - security: new NeMo scanner detecting CVE-2025-23304 Hydra
_target_injection in.nemomodel files (CVSS 7.6), with recursive config inspection and dangerous callable blocklist - security: detect CVE-2025-51480 ONNX
save_external_dataarbitrary file overwrite via external_data path traversal (CVSS 8.8) - security: detect CVE-2025-49655 TorchModuleWrapper deserialization RCE (CVSS 9.8).
- security: add CatBoost
.cbmscanner with strictCBM1format validation, bounded parsing, and suspicious command/network/script indicator checks - security: add dedicated scanner support for R serialized artifacts (
.rds,.rda,.rdata) with bounded decompression and static detection of executable symbol/payload indicators - security: add CNTK
.dnn/.cmfscanner with strict signature validation, bounded reads, and multi-signal suspicious content correlation - feat: add standalone compressed-wrapper scanner support for
.gz,.bz2,.xz,.lz4, and.zlibwith strict signature validation, decompression size/ratio safeguards, and inner-payload scanner routing - security: add RKNN
.rknnscanner with strictRKNNsignature detection, bounded metadata parsing, and contextual command/network/obfuscation checks - security: add Torch7 (
.t7,.th,.net) scanner with strict signature heuristics plus Lua execution primitive and dynamic module-loading detection - security: add native LightGBM scanner for
.lgb/.lightgbmand signature-validated.modelartifacts with strict XGBoost collision disambiguation and static command/network/path indicator checks - feat: add Llamafile executable scanner with bounded runtime-string analysis and embedded GGUF payload carving/forwarding
- feat: add CoreML
.mlmodelscanner with strict protobuf structure validation, custom layer/custom model detection, metadata abuse checks, and linked-model path safety checks - feat: add MXNet scanner support for paired
*-symbol.jsonand*-NNNN.paramsartifacts with strict contract validation, companion-file checks, and suspicious reference/payload detection - security: add TensorFlow MetaGraph (
.meta) scanner support with strict protobufcan_handle(), bounded MetaGraph parsing, unsafe op detection (PyFunc/PyCall/LoadLibrary), executable-context string checks, and payload-stuffing anomaly controls - security: add dedicated TorchServe
.marscanner with strict archive validation, bounded manifest/member reads, manifest policy checks, and recursive embedded payload scanning - security: detect CVE-2025-1716 pickle bypass via
pip.main()as dangerous callable (CVSS 9.8) - keras: detect CVE-2025-9906
enable_unsafe_deserializationconfig bypass in.kerasarchives (CVSS 8.6, safe_mode bypass) - security: detect CVE-2025-8747 Keras get_file gadget safe_mode bypass
- keras: detect CVE-2025-9905 H5 safe_mode bypass for Lambda layers (CVSS 7.3)
- keras: add CVE-2024-3660 attribution to Lambda layer detection in .keras and .h5 scanners (CVSS 9.8)
- keras: recursively inspect H5
training_configand.kerascompile_configfor custom losses and metrics, while allowlisting standard aliases and built-in preprocessing layers to reduce false positives - security: detect CVE-2025-10155 pickle protocol 0/1 payloads disguised as
.binfiles by extendingdetect_file_format()to recognize GLOBAL opcode patterns and addingposix/ntinternal module names to binary code pattern blocklist - security: detect CVE-2022-25882 ONNX external_data path traversal with CVE attribution, CVSS score, and CWE classification in scan results
- security: detect CVE-2024-27318 ONNX nested external_data path traversal bypass via path segment sanitization evasion
- security: restore ZIP scanner fallback for invalid
.mararchives so malicious ZIP payloads renamed to.marcannot bypass archive checks - security: flag risky import-only pickle references for
torch.jit,torch._dynamo,torch._inductor,torch.compile,torch.storage._load_from_bytes,numpy.f2py, andnumpy.distutilswhile preserving safe state-dict reconstruction paths - security: add low-severity pickle structural tamper findings for duplicate or misplaced
PROTOopcodes while avoiding benign binary-tail false positives - security: stop treating mixed-case valid pickle module names as implausible, so import and reduce checks no longer bypass on names like
PILor attacker-chosenEvilPkg - security: scan OCI layer members based on registered file extensions so embedded ONNX, Keras H5, and other real-path scanners are no longer skipped inside tar layers
- security: resolve bare-module TorchServe handler references like
custom_handlerto concrete archive members so malicious handler source is no longer skipped by static analysis - security: compare archive entry paths against the intended extraction root without following base-directory symlinks
- security: stop loading
.envfiles implicitly during JFrog helper import so untrusted working directories cannot rewrite proxy or auth-related environment variables - rules: preserve
rule_codemetadata through direct result aggregation and ensure dangerous advanced pickle globals emit explicit rule codes (with regression coverage) - rules: ignore unknown rule IDs in config files with warning logs, normalize rule-code casing in config parsing, and prevent invalid severity entries from being applied
- security: harden shared auth config storage and archive path sanitization to avoid insecure temp fallbacks, symlink overwrite abuse, and temp-root symlink traversal bypasses
- security: stop archive path sanitization from resolving attacker-controlled extraction-root symlinks, preventing symlinked temp directories from weakening traversal checks
- telemetry: refresh the cached telemetry client when runtime context changes and lazily initialize PostHog when telemetry is re-enabled in-process
- tests: add scanner literal
rule_coderegistry-consistency coverage to catch unknown rule identifiers early - cloud: harden cache path handling to prevent sibling-prefix bypasses from escaping cache boundaries, avoid deleting out-of-cache metadata paths during cleanup, and clean temporary cloud download directories on failure
- tests: unskip and restore cloud disk-space failure coverage; add regressions for cache boundary enforcement and temp-directory cleanup on download errors
- security: harden pickle scanner stack resolution to correctly track
STACK_GLOBALand memoizedREDUCEcall targets, preventing decoy-string andBINGETbypasses - security: flag pickle
EXT1/EXT2/EXT4extension-registry call targets inREDUCEanalysis to close EXT opcode bypasses - security: detect protocol 0/1 ASCII pickle signatures in generic file-format detection to prevent ZIP entry extension bypasses (e.g., malicious
payload.txt) - security: harden protocol 0/1 pickle format detection with bounded opcode parsing to catch prefixed payloads (e.g.,
MARK/LISTbeforeGLOBAL) while reducing plain-text false positives in ZIP entry scanning - security: keep opcode-level pickle analysis active when malformed streams trigger unicode/text parse errors after partial opcode extraction
- security: tighten safetensors magic-byte detection to require valid framed headers, preventing JSON and protocol 0 pickle misrouting
- security: analyze all Python files in TorchServe
.mararchives (including non-handler modules and__init__.py) for risky calls, import-time execution, and handler-to-utility import relationships
Security
- keras: detect CVE-2025-1550 arbitrary module references in
.kerasconfig.json (CVSS 9.8, safe_mode bypass) - security: treat
joblib.loadas always dangerous and remove it from pickle ML allowlist to block loader trampoline bypasses - security: tighten manifest trusted-domain matching to validate URL hostnames instead of substring matches
- security: make
.kerassuspicious file extension checks case-insensitive to catch uppercase executable/script payloads - security: block unsafe in-process
torch.loadinWeightDistributionScannerby default unless explicitly opted in - fix: tighten metadata scanner suspicious URL matching to use exact hostname/subdomain checks and add focused regression coverage
- fix: treat
.nemofiles as tar-compatible during file-type validation to avoid false extension/magic mismatch alerts - fix: pass XGBoost load-test file paths via subprocess argv instead of interpolating shell-quoted paths into
python -c, preventing backslash escape corruption on Windows-style paths - security: reject absolute OCI layer references so
.manifestfiles cannot scan host tarballs outside the OCI layout
Documentation
- update README and user docs for the
modelaudit metadatacommand, metadata safety guidance (--trust-loaders), and new NeMo format coverage - align maintainer/agent docs with current architecture and release workflow (metadata extractor component, dependency extras, and release-please + changelog guidance)
- align repository documentation around current scanner coverage, rule codes, package boundaries, and supported CI workflows
0.2.37 (2026-04-12)
Bug Fixes
- add CVE scanner coverage (01dec02)
- add size floor for zip compression ratio (#949) (5e66eeb)
- align SARIF scan metadata with CLI results (#934) (1a90415)
- allow generated TorchScript source files (#948) (53d0cdc)
- archives: honor nested header routing (fccdb91)
- avoid archive bin pickle routing (#962) (446df6b)
- avoid safetensors unicode metadata false positive (#945) (d595fde)
- bound standalone pickle stream reads (4d0cb84)
- catboost: redact finding urls (c65334c)
- cli: honor streaming file skips (49291ac)
- cli: redact cloud urls in output (#964) (0ee82ca)
- default unknown severities to info (#963) (9b27b9a)
- deps: update dependency tensorflow to >=2.21,<2.22 (#985) (2e3ac65)
- detectors: redact network urls in findings (7e28a46)
- dvc: restrict target paths (3bd9b68)
- flag pickle persistent ids (#938) (2cfba40)
- gguf: detect tensor bounds overflow (a4358ff)
- honor header-routed scanners (#941) (6740260)
- huggingface: redact source urls (73b538e)
- ignore pmml documentation urls (506aa75)
- jfrog: redact url secrets (4546eee)
- keras: redact archive urls (e532b0d)
- lightgbm: redact finding urls (d4f1fe2)
- manifest: redact url secrets (c831733)
- mark missing numpy format as operational (#958) (6d271d6)
- mark pickle parse failures inconclusive (8a0e3fd)
- metadata: redact suspicious urls (7af0d4d)
- metadata: reject symlink escapes (3869cf0)
- narrow flax suspicious key criticals (#957) (9276d24)
- narrow network c2 metadata patterns (fd9cc41)
- narrow openvino external library checks (#959) (e895872)
- narrow safetensors path metadata checks (#955) (4241780)
- narrow suspicious dunder string detection (#947) (e866760)
- nemo: scan referenced non-checkpoint suffixes (3ba4ff7)
- openvino: flag sidecar symlink escapes (772e796)
- openvino: redact library urls (241a667)
- preserve informational network findings (b39d312)
- reduce benign Keras Lambda bytecode noise (8cb5c29)
- require nested pickle execution evidence (d2ad631)
- route nested compressed archive members (e217b29)
- route nested compressed members (#944) (d839fe7)
- r: redact serialized urls (013bcf0)
- scanners: redact evidence secrets (3ae1383)
- skip prose-only network references (773eb88)
- skip protocol-only streaming pickle warning (#961) (dba3ebe)
- tighten pytorch zip pickle discovery (#953) (bfd9663)
- torchserve: redact manifest urls (4626a02)
Documentation
0.2.36 (2026-04-11)
Documentation
0.2.35 (2026-04-11)
Bug Fixes
- clean up oversized zip entry temps (#911) (66b4871)
- flag Paddle code patterns as warnings (#925) (32fa0b7)
- harden manifest parse boundaries (#922) (6f5b516)
- harden standalone pickle scanner (#901) (31f7dd3)
- mark corrupt NumPy object payloads inconclusive (#912) (ecba19d)
- mark incomplete MXNet scans inconclusive (#923) (a928ed7)
- mark incomplete sharded scans inconclusive (#909) (510d0fb)
- mark malformed GGUF scans inconclusive (#914) (9b3e216)
- mark malformed Keras H5 configs inconclusive (#917) (23671c3)
- mark malformed Keras ZIP configs inconclusive (#918) (d4ad8d8)
- mark malformed SafeTensors scans inconclusive (#913) (43913d6)
- mark malformed tflite scans inconclusive (#916) (07c871a)
- mark partial archive scans inconclusive (#907) (c8eb918)
- mark partial streaming scans inconclusive (#908) (3d47a10)
- mark unknown ONNX tensor dtypes inconclusive (#915) (35661b6)
- preserve picklescan stack state (#910) (fabac5c)
- recover malformed Jinja template configs (#920) (d619c8f)
- route corrupt catboost scans fail closed (#924) (052bb5f)
- traverse nemo yaml list configs (#919) (0d8d4fd)
- zip: fail closed on MAR handler parse errors (#896) (a06a620)
Documentation
0.2.34 (2026-04-10)
Bug Fixes
- flag Paddle code patterns as warnings instead of failing benign scans
- route corrupt CatBoost scans to fail closed outcomes
- mark incomplete MXNet scans inconclusive instead of clean
- harden manifest parse boundaries around malformed metadata
- recover malformed Jinja template configs as inconclusive scan outcomes
- traverse NeMo YAML list configs when checking suspicious targets
- mark malformed Keras ZIP configs inconclusive instead of clean
- mark malformed Keras H5 scans inconclusive instead of clean
- mark malformed TFLite scans inconclusive instead of clean
- mark malformed GGUF scans inconclusive instead of clean
- mark malformed SafeTensors scans inconclusive instead of clean
- preserve picklescan stack state across reused scanner runs
- mark partial streaming scans inconclusive when large-file streaming coverage is incomplete
- harden native code detection in model scanners (#897) (f4f661a)
0.2.33 (2026-04-09)
Features
Bug Fixes
- harden helper routing for zip-backed pickle checkpoints (#870) (3ebe0c0)
- make return paths explicit (#884) (e31c254)
- skip extraction for suspicious ZIP entries (358aa44)
Documentation
- clarify detection bypass severity policy (d8117a1)
0.2.32 (2026-04-05)
Bug Fixes
- detect punctuated TensorRT tmp paths (#867) (9607530)
- fail closed on OpenVINO DOCTYPE parse errors (#864) (f5b19c4)
- ignore OCI metadata URLs during layer discovery (#866) (0b24e3f)
- reduce PMML subprocess extension false positives (#869) (5e6f79d)
- tolerate bounded CoreML custom block truncation (#868) (34df06d)
0.2.31 (2026-04-04)
Bug Fixes
- clean up CodeQL quality findings (#862) (5fbcb10)
- detect long-gap protocol-0 pickle tails (#844) (cbc24b2)
- detect protocol 0/1 pickles with trailing junk (#827) (d07869d)
- fail closed on conflicting Keras ZIP config aliases (#847) (ab426b8)
- harden content-routed .keras ZIP recursive scans (#828) (a607df7)
- harden CoreML scanner (#859) (50da953)
- harden Flax msgpack stream scanning (#842) (34e4595)
- harden JAX checkpoint scanner heuristics (#837) (1042c20)
- harden Joblib raw/compressed pickle analysis (#841) (9d16470)
- harden Keras H5 scanner (#848) (aa0ef28)
- harden MAR duplicate-member analysis (#830) (8d4e056)
- harden NeMo target checks and YAML bounds (#839) (63ff67d)
- harden OCI layer scanner (#856) (637a4da)
- harden ONNX scanner (#857) (de304a7)
- harden OpenVINO scanner (#852) (a97b76e)
- harden PMML scanner (#860) (cbcd88a)
- harden post-budget pickle tail scan bounds (16d6db3)
- harden PyTorch binary chunk scanning (#846) (930c0bf)
- harden SevenZip scanner (#855) (8d0c362)
- harden skops archive routing, recursion, and scanner reporting (#829) (fb13f68)
- harden Skops CVE status and card fallback detection (#843) (9dd964f)
- harden TAR scanner (#854) (219ce54)
- harden TensorFlow MetaGraph scanner (#850) (2dacc9d)
- harden TensorFlow SavedModel scanner (#849) (f42b7f2)
- harden TensorRT scanner (#858) (c923b55)
- harden TFLite scanner (#851) (b1b1060)
- harden TorchServe MAR handler and manifest analysis (#840) (6fc0437)
- harden ZIP scanner (#853) (4ccec1a)
- reject raw trailers in zlib wrappers (#838) (3b15e2e)
- scan duplicate PyTorch ZIP members (#845) (4f63b22)
Documentation
0.2.30 (2026-03-30)
Bug Fixes
- always run binary fallback for parse-failed .bin files (#814) (f5f3c90)
- harden nested pickle detection against padded payloads (#812) (c15f53e)
- mark incomplete pickle scans as inconclusive (#810) (ade9296)
- normalize archive locations and route .skops ZIPs (#805) (f7c8277)
- preserve fail-closed pickle fallback semantics (#817) (e8a6db7)
- restore post-budget pickle opcode parity (#811) (d321309)
- use symbolic STACK_GLOBAL refs for pickle ML context (#813) (eb48c52)
- utils: recurse into cloud directories with size metadata (#819) (2d9852d)
0.2.29 (2026-03-29)
Features
- cli: add --no-whitelist and --strict flags for CI pipelines (636b813)
- detect pickle expansion attack heuristics (8e074fd)
- whitelist: warn when HuggingFace whitelist snapshot is stale (5a60871)
Bug Fixes
- add guarded CRC fallback for PyTorch ZIP scanning (5db1e71)
- cache: harden invalidation and skip operational failures (6492598)
- cli: propagate cache settings to registry downloads (d6cf508)
- core: count stream scans in files_scanned (#749) (50326bb)
- core: route misnamed archives by trusted file structure (cad90c3)
- deps: include py7zr in all extras (#759) (16cfae1)
- detection: tighten safetensors magic detection to prevent misrouting (109bca2)
- fail closed on pickle unknown opcode parse errors (#747) (a63979a)
- filtering: preserve disguised model files during directory scans (27058f5)
- generate release sbom from uv lock (#733) (a1019a8)
- harden pickle setitem target detection (#756) (877669c)
- huggingface: fail closed on listing errors and timeouts (f22ebbe)
- jfrog: fail closed on partial folder downloads (14e2ddd)
- keep json stdout clean for skipped files (#768) (0857b98)
- keras-zip: harden documentation padding bypass for CVE-2025-9906 (6e73043)
- keras: anchor safe Lambda pattern regexes to prevent code injection bypass (73fa571)
- keras: prevent spoofed built-in registered_name from hiding non-allowlisted modules (#736) (6d8350e)
- large-files: fail closed without bounded scanner coverage (a2317eb)
- make pickle operational errors explicit (2d75778)
- manifest: trust regional S3 manifest URLs (#763) (f43af54)
- mar: analyze all Python files in TorchServe MAR archives (dd2cf32)
- mar: analyze requirements.txt for supply chain attacks (5365583)
- metadata: harden metadata scanner userinfo URLs (#767) (07bf5a5)
- normalize streamed source path reporting (#765) (09431e0)
- onnx: add ai.onnx.ml to standard domain allowlist (c94f804)
- pickle: add budget-independent global/import byte scanner for large files (512dd18)
- pickle: add catch-all for unhandled opcodes in stack simulator (445b204)
- pickle: allow uppercase module segments in import checks (#757) (c1aeb55)
- pickle: detect nested pickle BINBYTES8 and BYTEARRAY8 payloads (#754) (814c7f2)
- pickle: harden blocklist — copyreg, _pickle.Unpickler, functools.reduce (fe04d9a)
- pickle: surface large-file raw pattern coverage limits (#769) (d9904f2)
- pickle: track BUILD opcode setstate exploitation (7e8c370)
- pickle: treat scan timeouts as unsuccessful without regressing tail scans (075adcd)
- preserve exit code 1 for zero-file findings (#764) (34d25e7)
- preserve scanner execution for chunked large files (#745) (8d93f1d)
- preserve validated PE detections in pickle scans (#746) (017202c)
- prevent ExecuTorch polyglot ZIP bypass (#743) (e06d0e8)
- route zip-backed pytorch containers in pickle scanner (0390a00)
- routing: complete format_to_scanner primary routing map (de69f71)
- safetensors: add missing BF16/BOOL/FP8 dtypes for size validation (f2f2574)
- safetensors: apply MAX_HEADER_BYTES limit in scan() to prevent DoS (7a847a7)
- savedmodel: scan assets/ directory for executable content (04d2a0c)
- scan padded follow-on pickle streams (#755) (8727d03)
- security: block streamed symlink traversal outside scan roots (#751) (aee6656)
- security: bound embedded .keras weight extraction to prevent zip-bomb DoS (#737) (1cc0e46)
- security: bound MAR fallback python handler reads (#735) (88e42b9)
- security: harden manifest URL trust checks and timeout handling (#760) (9ccc5f3)
- security: preserve scannable artifacts in directory filtering (#758) (7666930)
- security: preserve shared depth across nested archive types (#753) (607b506)
- security: recurse into extensionless nested ZIP members (#752) (a2dfea9)
- security: recurse into nested sevenzip archives by content (#761) (3b0e3dc)
- security: require explicit HuggingFace provenance for whitelist downgrades (#750) (582e361)
- security: route nested sevenzip members through core scanning (#762) (92ffdf7)
- sevenzip: recurse into misnamed nested archives (2cc5423)
- streaming: avoid materializing file iterators (7a9ae37)
- tflite: stop after excessive subgraph counts (64b08fa)
- whitelist: preserve explicit HF download provenance (#766) (7e187cb)
Documentation
- agents: tighten validation and routing guidance (335b656)
- normalize unreleased changelog section (#741) (5e66490)
0.2.28 (2026-03-20)
Features
- add rule codes to all security checks (#255) (330e7df)
- keras: detect StringLookup external vocabulary paths (#727) (20e9852)
- security: detect Keras HDF5 external weight references (#729) (6db8e27)
Bug Fixes
- accept valid ExecuTorch FlatBuffers binaries (93caa97)
- add torch and numpy helper primitive coverage (#706) (b0a6a11)
- block dill recursive loader globals (#695) (0d88a4b)
- block legacy httplib pickle aliases (#703) (24b789a)
- bound advanced pickle global extraction (#700) (d9fe283)
- bound skops zip entry reads and enforce uncompressed size limit (#702) (a91577d)
- bound XZ decompression memory in r_serialized scanner (26d5b44)
- bound zlib wrapper decompression output (#681) (8bb9cc2)
- ci: reorder provenance job steps to prevent SBOM generation failure (#646) (d4ab381)
- deps: move optional onnx extra to 1.21.0rc3 for CVE-2026-28500 mitigation (#726) (01b5f4f)
- deps: update dependency numpy to >=2.4.3,<2.5 (#669) (9d81218)
- detect pickle proto structural tampering (#697) (0a8a737)
- detect risky import-only pickle ML surfaces (#696) (a272307)
- enforce decompression limits for compressed tar wrappers (841cc5e)
- expand dangerous pickle primitive coverage (#705) (40e45ac)
- fail closed on malformed STACK_GLOBAL operands (#704) (9a1b9a1)
- handle Windows backslashes in XGBoost subprocess loader (#656) (ba30b81)
- harden archive path sanitization (#666) (9d77d50)
- harden cloud download async/cache safety and cleanup (#655) (e14ea61)
- harden import-only pickle global detection (#691) (d27d90d)
- harden keras custom object detection (#694) (7651298)
- harden rule config parsing and debug path privacy (#648) (a073187)
- harden shared config writes and archive path sanitization (#660) (60de400)
- harden xgboost subprocess import isolation (#701) (2df2d78)
- include streamed artifacts in SBOM output for --stream scans (#672) (48d8d54)
- keras attack-vector fixes for coverage gaps in h5 and keras zip scanning (#689) (863c884)
- keras: derive safe layer inventory from exports (#718) (9b8d143)
- mark flaky timing test as performance to skip in CI (#670) (9c47f7e)
- numpy: downgrade benign object-dtype CVE attribution to info (#723) (b7cc190)
- preserve duplicate paths with spaces (#690) (ea7c6d9)
- preserve Hugging Face artifacts in SBOM output (#673) (49c7eca)
- preserve rule codes through scan aggregation (#650) (d71a219)
- prevent jfrog folder download path traversal (#679) (6f226a4)
- prevent unbounded tensor proto allocations in TF weight extraction (#685) (ae2b01c)
- recurse into NumPy object pickle payloads (9893c0c)
- reduce Keras ZIP custom-object false positives (#716) (165b238)
- refresh telemetry client state (#658) (7b6ea2f)
- reject absolute OCI layer references (#659) (722131a)
- remove pickle hasattr allowlist entries (#692) (4d64cc8)
- resolve bare torchserve handler modules (#664) (3ae3535)
- restore raw telemetry fields and harden model_name extraction (#649) (275f087)
- restrict trusted jfrog hosts for auth (#661) (d959a0d)
- route compound tar wrappers to tar scanner (#707) (79c0772)
- route oci layer members via extracted paths (#663) (1395af0)
- scan TensorFlow SavedModel function definitions for dangerous ops (#677) (31f4715)
- security: avoid torch import-hijack in PyTorch ZIP CVE checks (#728) (badd611)
- security: bound pickle metadata reads in metadata extraction (f1d0698)
- security: detect nested kwargs URLs in CVE-2025-8747 check (#682) (9431fae)
- security: reduce benign pickle scanner noise (#724) (237db31)
- security: require explicit trust for local scan config (#714) (25c6936)
- security: restore ZIP fallback scanning for invalid .mar archives (#711) (55de730)
- security: use conservative PyTorch version selection for CVE checks (#684) (ef5c5e6)
- stop double-scanning PyTorch ZIP archives (e4d36d4)
- stop importing dotenv in jfrog helper (#662) (d20fda3)
- stop suppressing mixed-case pickle modules (18cdd31)
- stream tar member extraction during scan (#665) (3de3048)
- telemetry: preserve model refs while stripping secrets (#717) (d19d6fd)
- tighten dill MemoryError downgrade gating (5eefa15)
- tighten llamafile runtime allowlist matching (#683) (8592a80)
- use major GitHub Action refs (#680) (7965314)
0.2.27 (2026-03-05)
Features
- add CatBoost .cbm scanner support (#627) (9138066)
- add CNTK scanner support (#629) (74a60b9)
- add CoreML .mlmodel scanner support (#635) (4e24291)
- add llamafile executable scanner support (#634) (8d2c37d)
- add Model Metadata Extractor feature (#383) (ff66f33)
- add native LightGBM scanner support (#633) (d3aca64)
- add R serialized scanner support (#628) (e27667c)
- add RKNN scanner support (#631) (f1bbfb7)
- add standalone compressed wrapper scanner (#630) (c5f0dba)
- add TensorFlow MetaGraph scanner support (#637) (7c3c25d)
- add Torch7 scanner support (#632) (2e6f2c4)
- security: add CVE-2019-6446 attribution for NumPy object dtype RCE (#610) (5d707b5)
- security: add CVE-2022-25882 attribution to ONNX external_data path traversal (#606) (4d69e83)
- security: add CVE-2024-3660 Lambda code injection attribution (#604) (60ca40f)
- security: add NeMo scanner for CVE-2025-23304 Hydra target injection (#609) (6d2dee3)
- security: detect 3 PyTorch CVEs (JIT eval, RPC injection, RemoteModule RCE) (#611) (98f2af6)
- security: detect 4 PyTorch CVEs via static scanning (#595) (024f583)
- security: detect CVE-2024-27318 ONNX nested path traversal bypass (#607) (fe8837c)
- security: detect CVE-2025-10155 pickle protocol 0/1 bypass via .bin extension (#605) (88a5901)
- security: detect CVE-2025-1550 Keras safe_mode bypass (#599) (432c383)
- security: detect CVE-2025-1716 pickle bypass via pip.main() (#598) (2f2ae20)
- security: detect CVE-2025-49655 TorchModuleWrapper RCE (#600) (0c12d2d)
- security: detect CVE-2025-51480 ONNX save_external_data file overwrite (#608) (fe04271)
- security: detect CVE-2025-8747 get_file gadget bypass (#602) (16308d0)
- security: detect CVE-2025-9905 H5 safe_mode bypass (#603) (1676693)
- security: detect CVE-2025-9906 Keras enable_unsafe_deserialization config bypass (#601) (b493806)
Bug Fixes
- block joblib.load pickle trampoline (#626) (966c223)
- ci: resolve 4 release pipeline failures (#572) (7e2e7ed)
- ci: resolve Ruff failures on main (#621) (bd186f0)
- cli: surface operational scan error status in text output (#578) (ddbbec6)
- close pickle EXT opcode bypass (#623) (ffb5ec1)
- deps: promote msgpack to core dependency for Flax scanner (#583) (ebba6b2)
- detect proto0/1 pickles inside zip entries (#624) (2bce49d)
- downgrade non-traversal ONNX external data refs to WARNING (#642) (44eb3ab)
- eliminate false positive in skops Unsafe Joblib Fallback Detection (#584) (c1dd2a6)
- handle MemoryError gracefully for joblib/sklearn pickle files (#645) (f8599fe)
- pickle-scanner: three targeted false-positive reductions (#591) (7a5567e)
- preserve opcode analysis on malformed pickle tails (#625) (4fe4dee)
- prevent false positives in TF SavedModel scanner (#588) (89282e2)
- report actual file size in scan summary when scanner exits early (#587) (7d066fb)
- resolve false positive for .keras ZIP files (Keras 3.x) (#582) (f575769)
- resolve ONNX weight extraction failure (#589) (3f54602)
- security: close scanner RCE bypasses and add regressions (#518) (e736ebb)
- security: harden pickle scanner blocklist and multi-stream analysis (#581) (f0c7246)
- stabilize nightly performance CI and optimize pickle opcode analysis (#619) (e5dcec5)
- suppress false positives in PaddlePaddle scanner (#586) (ec7fc48)
- tests: prevent multiple_stream_attack fixture rewrites (#580) (0eb47c9)
- tests: resolve 3 nightly CI failures across Linux and Windows (#576) (dd115d1)
- tests: resolve nightly CI failures on Linux and Windows (#597) (7f88c52)
- tflite: recognize .tflite format without tflite package installed (#585) (8276184)
- tighten metadata URL hostname matching (#617) (c2af8c1)
Documentation
- add CVE detection checklist from 13 CVE implementation learnings (#612) (7ea1869)
- audit and refresh README, user docs, and maintainer guides (#643) (015acdc)
- rewrite SECURITY.md with comprehensive vulnerability policy (#594) (968a2c2)
- update scanner architecture example (#579) (20de35d)
0.2.26 (2026-02-24)
Bug Fixes
- ci: pin protoc version for vendored proto reproducibility (#548) (03e9d35)
- cli: add --cache-dir and simplify defaults wording (#550) (b8701dd)
- cli: fail fast when glob patterns match nothing (#519) (404104b)
- deps: update dependency xgboost to >=3.2,<3.3 (#507) (4489e97)
- enforce consistent scanner patterns across all scanners (#564) (dd6b8d2)
- improve test suite reliability and safety (#565) (4bd04a7)
- remove security anti-patterns from scanning infrastructure (#562) (d02cd0b)
- security: close critical scanner and CI gating gaps (#553) (807a8aa)
- security: resolve CodeQL alerts for workflow permissions and sensitive logging (#570) (d2dfc79)
- security: resolve remaining audit findings (#4-#8) (#556) (7430436)
- security: use URL hostname parsing instead of substring matching (#571) (b4d3696)
- test: relax benchmark timing assertions for Windows CI (#569) (b06faac)
Documentation
- clarify README exit codes (#568) (e57a0de)
- fix accuracy issues across AGENTS.md, README, and CONTRIBUTING (#566) (880e7a4)
- open-source: add user trust docs batch (#534) (dd5e676)
- readme: add cache management flag (#521) (33d74bd)
- ship next-phase open-source readiness docs (#532) (c88035d)
- trim README to essentials, fix inaccuracies (#517) (59c056c)
0.2.25 - 2026-02-12
Features
- add binary patterns for native code loading (#499) (ef638f1)
- add comprehensive Windows compatibility support (#474) (d62574e)
- add detection for dangerous TensorFlow operations (#494) (6c4c0c9)
- add detection for memo-based and extension registry pickle opcodes (#493) (72509f7)
- add getattr-based evasion detection patterns (#500) (87ba295)
- add Git LFS pointer detection (#488) (6413ae3)
- add Keras subclassed model detection (#503) (d9e5663)
- add lambda variadic argument validation (#501) (52a6622)
- add PyTorch ZIP archive security controls (#502) (09ab087)
- eliminate TensorFlow dependency with vendored protobuf stubs (#485) (56cec5e)
- expand SUSPICIOUS_GLOBALS with process and memory modules (#495) (8637d2b)
Bug Fixes
- add content-based CVE detection to SkopsScanner (#498) (89895cb)
- add logging to critical exception handlers in pickle scanner (#492) (b6b06cb)
- add logging to silent exception handlers in secrets detector (#491) (b59f8a4)
- add security keywords to QueueEnqueueV2 TF op explanation (#511) (1d93483)
- ci: ensure numpy compatibility job runs (#478) (7266160)
- deps: bump pillow 12.1.0→12.1.1 and cryptography 46.0.4→46.0.5 (#513) (5b18d49)
- deps: update dependency fickling to v0.1.7 [security] (#479) (292eb23)
- improve Python version requirement UX (#508) (a44d8bb)
- reduce false positive scan warnings for HuggingFace models (#514) (b545c11)
- reduce pickle scanner false positives for BERT and standalone REDUCE opcodes (#510) (94c22d6)
- remove duplicate whitelist downgrading in add_check() (#490) (a8c52bc)
- remove variable shadowing for skip_file_types parameter (#489) (bcf99ea)
- use deterministic data patterns in anomaly detector tests (#477) (df11759)
0.2.24 - 2025-12-23
Bug Fixes
- deps: update dependency contourpy to <1.3.4 (#463) (16fb916)
- deps: update dependency fickling to v0.1.6 [security] (#462) (9413ddc)
- deps: update dependency xgboost to v3 (#469) (97adbbc)
- resolve release-please CHANGELOG formatting race condition (#457) (4347b83)
0.2.23 - 2025-12-12
Documentation
- consolidate agent guidance (#453) (a01ceff)
- restructure AGENTS.md and CLAUDE.md following 2025 best practices (#451) (e87de51)
0.2.22 - 2025-12-10
Added
- feat: add
modelaudit debugcommand for troubleshooting - outputs comprehensive diagnostic information including version, platform, environment variables, authentication status, scanner availability, NumPy compatibility, cache status, and configuration in JSON or pretty-printed format; useful for bug reports and support interactions
0.2.21 - 2025-12-09
Fixed
- fix: resolve UnicodeDecodeError when scanning PyTorch .pkl files saved with default ZIP serialization - torch.save() uses ZIP format by default since PyTorch 1.6 (
_use_new_zipfile_serialization=True), but ModelAudit was incorrectly routing these files to PickleScanner which failed to parse the ZIP header. Now correctly routes ZIP-format .pkl files to PyTorchZipScanner.
0.2.20 - 2025-12-01
Added
- feat: detect cloud storage URLs in model configs (AWS S3, GCS, Azure Blob, HuggingFace Hub) - identifies external resource references that could indicate supply chain risks or data exfiltration vectors
- feat: add URL allowlist security scanning to manifest scanner - uses 164 trusted domains to flag untrusted URLs in model configs as potential supply chain risks
- feat: detect weak hash algorithms (MD5, SHA1) in model config files - scans manifest files for hash/checksum fields using cryptographically broken algorithms and reports WARNING with CWE-328 reference; SHA256/SHA512 usage is confirmed as strong
- feat: add comprehensive analytics system with Promptfoo integration - opt-out telemetry for usage insights, respects
PROMPTFOO_DISABLE_TELEMETRYandNO_ANALYTICSenvironment variables - feat: auto-enable progress display when output goes to file - shows spinner/progress when stdout is redirected to a file
Fixed
- fix: resolve false positives in pickle and TFLite scanners - improved detection accuracy
- fix: clean up tests for CI reliability - removed flaky tests and improved test isolation
0.2.19 - 2025-11-24
Fixed
- fix: resolve Jinja2 SSTI false positives from bracket notation - refined obfuscation pattern to only match dunder attributes (
["__class__"]) instead of legitimate dict access (["role"]), and fixed regex bug where|format\(matched any pipe character - fix: remove overly broad secret detection pattern - replaced generic
[A-Za-z0-9]{20,}pattern with specific well-known token formats (GitHub, OpenAI, AWS, Slack) to eliminate false positives on URLs and model IDs - fix: resolve msgpack file type validation false positive - unified format name inconsistency where functions returned different values (
"msgpack"vs"flax_msgpack"), causing validation failures on legitimate MessagePack files - fix: add HuggingFace training utilities to pickle safe globals - added safe Transformers, Accelerate, and TRL classes (HubStrategy, SchedulerType, DistributedType, DeepSpeedPlugin, DPOConfig, etc.) to reduce false positives on training checkpoints
0.2.18 - 2025-11-20
Fixed
- fix: exclude INFO/DEBUG checks from success rate calculation - success rate now only includes security-relevant checks (WARNING/CRITICAL), with informational checks (INFO/DEBUG) shown separately in "Failed Checks (non-critical)" section
- fix: missing whitelist logic in validation checks - whitelist downgrading now correctly applies to validation result instantiations
- fix: resolve PyTorch ZIP scanner hang on large models - improved memory-mapped file handling and timeout configuration
- fix: additional severity downgrades - further reduced false positives across multiple scanners
Changed
- chore: standardize on
add_check()API - internal code now uses the modernadd_check()method for structured check reporting with explicit pass/fail status
0.2.17 - 2025-11-19
Fixed
- fix: eliminate false positive WARNINGs on sklearn/joblib models (removed overly broad pattern matching)
- Removed
b"sklearn",b"NumpyArrayWrapper", andb"numpy_pickle"from binary pattern detection - These patterns flagged ALL legitimate sklearn/joblib models (100% false positive rate)
- Regex CVE patterns still detect actual exploits requiring dangerous combinations
- Reduces false positive WARNING rate by 77% (10 out of 13 WARNINGs eliminated)
- Removed
- fix: NEWOBJ/OBJ/INST opcodes now recognize safe ML classes (eliminates sklearn model false positives)
- Applied same safety logic as REDUCE opcode: check if class is in ML_SAFE_GLOBALS allowlist
- sklearn models like LogisticRegression now correctly identified as INFO instead of WARNING
- Added support for nested sklearn modules (e.g., sklearn.linear_model._logistic)
- Added joblib.numpy_pickle.NumpyArrayWrapper and dtype.dtype to safe class list
- fix: handle joblib protocol mismatches gracefully (protocol 4 files using protocol 5 opcodes)
- joblib files may declare protocol 4 but use protocol 5 opcodes like READONLY_BUFFER (0x0f)
- Scanner now parses as much as possible before unknown opcodes, logs INFO instead of failing
- Eliminates false positive "Invalid pickle format - unrecognized opcode" WARNING on joblib files
- fix: accept ZIP magic bytes for .npz files (NumPy compressed format is ZIP by design)
- .npz files ARE ZIP archives containing multiple .npy files (numpy.savez format)
- Now accepts both "zip" and "numpy" header formats for .npz extension
- Fixed case-sensitivity bug: MODEL.NPZ, model.Npz now handled correctly
- fix: handle XML namespaces in PMML root element validation
- PMML 4.x files with namespaces like
{http://www.dmg.org/PMML-4_4}PMMLnow recognized - Strips namespace prefix before comparing tag name
- PMML 4.x files with namespaces like
- fix: add validation to prevent TFLite scanner crashes on malformed files
- Pre-validates magic bytes ("TFL3") before parsing
- Prevents buffer overflow crashes: "unpack_from requires a buffer of at least X bytes"
- Added security rationale ("why" field) to magic bytes check
0.2.16 - 2025-11-04
Added
- feat: content hash generation for regular scan mode - all scans (not just streaming) now generate
content_hashfield for model deduplication and verification
Changed
- refactor: rename
--scan-and-deleteflag to--streamfor clarity - streaming mode is now invoked with the more intuitive--streamflag
0.2.15 - 2025-10-31
Added
- feat: universal streaming scan-and-delete mode for all sources to minimize disk usage
- New
--scan-and-deleteCLI flag works with ALL sources (not just HuggingFace):- HuggingFace models (
hf://orhttps://huggingface.co/) - Cloud storage (S3, GCS:
s3://,gs://) - PyTorch Hub (
https://pytorch.org/hub/) - Local directories
- HuggingFace models (
- Files are downloaded/scanned one-by-one, then deleted immediately
- Computes SHA256 hash for each file and aggregate content hash for deduplication
- Adds
content_hashfield to scan results for identifying identical models - Ideal for CI/CD or constrained disk environments where downloading entire models (100GB+) isn't feasible
- New
Changed
- chore: move cloud storage dependencies (fsspec, s3fs, gcsfs) to default install - S3, GCS, and cloud storage now work without [cloud] extra
Fixed
- fix: centralize MODEL_EXTENSIONS to ensure all scannable formats are downloaded from HuggingFace
- Created single source of truth for model extensions (62+ formats including GGUF)
- Previously: GGUF files relied on fallback download (inefficient, downloads all files)
- Now: GGUF, JAX, Flax, NumPy and other formats are properly detected and selectively downloaded
- Dynamically extracts extensions from scanner registry to stay in sync
- fix: restore fallback behavior in streaming downloads to maintain parity with non-streaming mode
0.2.14 - 2025-10-23
Fixed
- fix: eliminate false positives across URL detection, CVE checks, GGUF parsing, and secret detection (#412)
- fix: improve shebang detection, fix fsspec usage, and resolve UnboundLocalError (#411)
0.2.13 - 2025-10-23
Added
- feat: huggingface model whitelist (#409)
Fixed
- fix: eliminate CVE-2025-32434 false positives for legitimate PyTorch models (#408)
0.2.12 - 2025-10-22
Fixed
- fix: remove non-security format validation checks across scanners (#406)
- fix: eliminate false positives in stack depth, GGUF limits, and builtins detection (#405)
0.2.11 - 2025-10-22
Fixed
- fix: INFO and DEBUG severity checks no longer count as failures in success rate calculations
0.2.10 - 2025-10-22
Fixed
- fix: eliminate false positive REDUCE warnings for safe ML framework operations (#398)
- fix: eliminate ONNX custom domain and PyTorch pickle false positives (#400)
- fix: eliminate false positive JIT/Script warnings on ONNX files (#399)
0.2.9 - 2025-10-21
Added
- feat: add context-aware severity for PyTorch pickle models (#395)
- Implement SafeTensors detection utility to identify safer format alternatives
- Add import analysis to distinguish legitimate vs malicious pickle imports
- Consolidate opcode warnings into single check with evidence counts
- Add
import_referencefield to pickle scanner GLOBAL checks for analysis - Provide actionable recommendations (use SafeTensors format)
Changed
- feat: rewrite PyTorch pickle severity logic with context-awareness (#395)
- CRITICAL: malicious imports detected (os.system, subprocess, eval)
- WARNING: legitimate imports + SafeTensors alternative available
- INFO: legitimate imports + no SafeTensors alternative
- Reduces false positives while maintaining security detection accuracy
- Example: sentence-transformers/all-MiniLM-L6-v2 now shows WARNING (was CRITICAL)
0.2.8 - 2025-10-21
Added
- feat: add skops scanner for CVE-2025-54412/54413/54886 detection (#392)
- Implement dedicated skops scanner for .skops model files
- Detect CVE-2025-54412 (OperatorFuncNode RCE vulnerability)
- Detect CVE-2025-54413 (MethodNode dangerous attribute access)
- Detect CVE-2025-54886 (Card.get_model silent joblib fallback)
- Add ZIP format validation and archive bomb detection
Changed
- refactor: remove non-security checks prone to false positives (#391)
- Remove blacklist checks from manifest scanner
- Remove model name policy checks from manifest scanner
- Streamline XGBoost scanner by removing non-security validation checks
- Reduce false positives in metadata scanner
Fixed
- fix: resolve XGBoost UBJ crash and network scanner false positives (#392)
- Fix UBJ format JSON serialization crash by sanitizing bytes objects to hex strings
- Eliminate network scanner false positives for pickle/joblib ML models by adding ML context awareness
- Add comprehensive XGBoost testing documentation with 25-model test corpus
0.2.7 - 2025-10-20
Fixed
- fix: improve XGBoost scanner severity levels and reduce false positives (#389)
- Handle string-encoded numeric values in XGBoost JSON models
- Add deterministic JSON validation to prevent claiming non-XGBoost files
- Implement tiered file size thresholds (INFO → WARNING) for large models
- Downgrade metadata scanner generic secret patterns from WARNING to INFO
- Reduce false positives for BibTeX citations and code examples in README files
- fix: prevent ML confidence bypass and hash collision security exploits (#388)
- Enable --verbose flag and accurate HuggingFace file sizes
- Remove CoreML scanner and coremltools dependency
- fix: enable advanced TorchScript vulnerability detection (#384)
- Enable comprehensive detection for serialization injection, module manipulation, and bytecode injection patterns
Changed
- refactor: reorganize codebase into logical module structure (#387)
- Create detectors/ module for security detection logic
- Improve maintainability and reduce import complexity
- chore(deps): bump tj-actions/changed-files from v46 to v47 (#386)
0.2.6 - 2025-09-10
Added
- feat: add comprehensive JFrog folder scanning support (#380)
- feat: add comprehensive XGBoost model scanner with security analysis (#378)
- feat: consolidate duplicate caching logic into unified decorator (#347)
- test: improve test architecture with dependency mocking (#374)
Fixed
- fix: exclude Python 3.13 from NumPy 1.x compatibility tests (#375)
0.2.5 - 2025-09-05
Added
- feat: upgrade to CycloneDX v1.6 (ECMA-424) with enhanced ML-BOM support (#364)
- feat: add 7-Zip archive scanning support (#344)
- feat: re-enable check consolidation system (#353)
- feat: integrate ty type checker and enhance type safety (#372)
Changed
- BREAKING: drop Python 3.9 support, require Python 3.10+ minimum
- feat: add Python 3.13 support
- feat: consolidate CLI from 25 to 12 flags using smart detection (#359)
- feat: enhance pickle static analysis with ML context awareness (#358)
- feat: enhance check consolidation system with PII sanitization and performance improvements (#356)
- docs: update AGENTS.md with exact CI compliance instructions (#357)
- docs: rewrite README with professional technical content (#370)
- feat: improve logging standards and consistency (#355)
- chore(deps): bump the github-actions group with 2 updates (#362)
- chore: update dependencies and modernize type annotations (#360)
- chore: remove unnecessary files from root directory (#369)
Fixed
- fix: handle GGUF tensor dictionaries in SBOM asset creation (#363)
- fix: correct release dates in CHANGELOG.md (#354)
- fix: resolve SBOM generation FileNotFoundError with URLs (#373)
0.2.4 - 2025-08-28
Added
- feat: improve CVE-2025-32434 detection with density-based analysis (#351)
- feat: implement graceful degradation and enhanced error handling (#343)
- feat: improve PyTorch ZIP scanner maintainability by splitting scan() into smaller functions (#346)
- feat: add SARIF output format support for integration with security tools and CI/CD pipelines (#349)
- feat: optimize cache performance by reducing file system calls (#338)
- feat: comprehensive task list update and critical CLI usability audit (#340)
- feat: add cache management CLI commands mirroring promptfoo's pattern (#331)
- feat: add comprehensive metadata security scanner and enhanced HuggingFace support (#335)
- feat: add comprehensive CVE detection for pickle/joblib vulnerabilities (#326)
- feat: add Jinja2 template injection scanner (#323)
- feat: comprehensive deep Pydantic integration with advanced type safety (#322)
- feat: optimize CI for faster feedback (#320)
- feat: skip SafeTensors in WeightDistributionScanner for performance (#317)
- feat: add Pydantic models for JSON export with type safety (#315)
- feat: add support for multi-part archive suffixes (#307)
- docs: add comprehensive CI optimization guide (#319)
- docs: add Non-Interactive Commands guidance to AGENTS.md (#318)
- docs: add comprehensive publishing instructions (#302)
- test: speed up tests and CI runtime (#316)
- test: cover Windows path extraction scenarios (#313)
- feat: detect dangerous TensorFlow operations (#329)
- feat: enhance pickle scanner with STACK_GLOBAL and memo tracking (#330)
- feat: detect Windows and Unix OS module aliases to prevent system command execution via
ntandposix
Changed
- chore: organize root directory structure (#341)
- chore: make ctrl+c immediately terminate if pressed twice (#314)
Fixed
- fix: aggregate security checks per file instead of per chunk (#352)
- fix: eliminate circular import between base.py and core.py (#342)
- fix: default bytes_scanned in streaming operations (#312)
- fix: validate directory file list before filtering (#311)
- fix: tighten ONNX preview signature validation (#310)
- fix: recurse cloud object size calculations (#309)
- fix: handle missing author in HuggingFace model info (#308)
- fix: handle PyTorch Hub URLs with multi-part extensions (#306)
- fix: avoid duplicated sharded file paths (#305)
- fix: handle None values in Keras H5 scanner to prevent TypeError (#303)
0.2.3 - 2025-08-21
Added
- feat: increase default max_entry_size from 10GB to 100GB for large language models (#298)
- feat: add support for 1TB+ model scanning (#293)
- docs: improve models.md formatting and organization (#297)
Fixed
- fix: improve cache file skip reporting to not count as failed checks (#300)
- fix: eliminate ZIP entry read failures with robust null checking and streaming (#299)
0.2.2 - 2025-08-21
Added
- feat: increase default scan timeout to 1 hour (#292)
- feat: improve CLI output user experience with verbose summary (#290)
- feat: add promptfoo authentication delegation system (#287)
- feat: expand malicious model test corpus with 42+ new models (#286)
- feat: streamline file format detection I/O (#285)
- feat: add comprehensive progress tracking for large model scans (#281)
- feat: raise large model thresholds to 10GB (#280)
- feat: enable scanner-driven streaming analysis (#278)
- feat: safely parse PyTorch ZIP weights (#268)
- feat: add comprehensive authentication system with semgrep-inspired UX (#50)
- docs: document security features and CLI options in README (#279)
Changed
- perf: cache port regex patterns for network detector (#269)
- refactor: reduce file handle usage in format detection (#283)
Fixed
- fix: eliminate SafeTensors recursion errors with high default recursion limit (#295)
- fix: add interrupt handling to ONNX scanner for graceful shutdown (#294)
- fix: eliminate duplicate checks through content deduplication (#289)
- fix: implement ML-context-aware stack depth limits to eliminate false positives (#284)
- fix: optimize directory detection (#282)
- fix: include license files in metadata scan (#277)
- fix: validate cloud metadata before download (#276)
- fix: handle async event loop in cloud download (#273)
- fix: add pdiparams extension to cloud storage filter (#272)
- fix: streamline magic byte detection (#271)
- fix: close cloud storage filesystems (#267)
- fix: flag critical scan errors (#266)
- fix: finalize early scan file exits (#265)
- fix: isolate network detector custom patterns (#264)
- fix: warn when JFrog auth missing (#263)
- fix: refine dangerous pattern detection check (#262)
- fix: handle deeply nested SafeTensors headers (#244)
Removed
- chore: remove outdated markdown documentation files (#296)
0.2.1 - 2025-08-15
Added
- feat: enhance timeout configuration for progressive scanning (#252)
- feat: add Keras ZIP scanner for new .keras format (#251)
- feat: add enhanced TensorFlow SavedModel scanner for Lambda layer detection (#250)
- feat: add compile() and eval() variants detection (#249)
- feat: improve os/subprocess detection for command execution patterns (#247)
- feat: add runpy module detection as critical security risk (#246)
- feat: add importlib and runpy module detection as CRITICAL security issues (#245)
- feat: add webbrowser module detection as CRITICAL security issue (#243)
- feat: add record path and size validation checks (#242)
- feat: enhance detection of dangerous builtin operators (#241)
- feat: add network communication detection (#238)
- feat: add JIT/Script code execution detection (#237)
- feat: add embedded secrets detection (#236)
- feat: add comprehensive security check tracking and reporting (#235)
- feat: add JFrog integration helper (#230)
- feat: add PyTorch Hub URL scanning (#228)
- feat: add tar archive scanning (#227)
- feat: add SPDX license checks (#223)
- feat: add RAIL and BigScience license patterns (#221)
- feat: expand DVC targets during directory scan (#215)
- feat: adjust SBOM risk scoring (#212)
- feat: add py_compile validation to reduce false positives (#206)
- feat: add disk space checking before model downloads (#201)
- feat: add interrupt handling for graceful scan termination (#196)
- feat: add CI-friendly output mode with automatic TTY detection (#195)
Changed
- perf: use bytearray for chunked file reads (#217)
- chore: improve code professionalism and remove casual language (#258)
- refactor: remove unreachable branches (#222)
- refactor: remove type ignore comments (#211)
Fixed
- fix: improve detection of evasive malicious models and optimize large file handling (#256)
- fix: eliminate false positives and false negatives in model scanning (#253)
- fix: improve PyTorch ZIP scanner detection for .bin files (#248)
- fix: add dangerous pattern detection to embedded pickles in PyTorch models (#240)
- fix: reduce false positives in multiple scanners (#229)
- fix: cast sbom output string (#220)
- fix: stream zip entries to temp file (#218)
- fix: handle broken symlinks safely (#214)
- fix: enforce UTF-8 file writes (#213)
- fix: update PyTorch minimum version to address CVE-2025-32434 (#205)
- fix: add main.py module and improve interrupt test reliability (#204)
- fix: resolve linting and formatting issues (#203)
- fix: return non-zero exit code when no files are scanned (#200)
- fix: improve directory scanning with multiple enhancements (#194)
- fix: add missing type annotations to scanner registry (#191)
- fix: resolve CI timeout by running only explicitly marked slow/integration tests (#190)
- fix: change false positive messages from INFO to DEBUG level (#189)
Security
- fix: resolve PyTorch scanner pickle path context and version bump to 0.2.1 (#257)
0.2.0 - 2025-07-17
Added
- feat: add scan command as default - improved UX with scan as the default command (#180)
- feat: add TensorRT engine scanner - support for NVIDIA TensorRT optimized models (#174)
- feat: add Core ML model scanner - support for Apple's Core ML .mlmodel format (#173)
- feat: add PaddlePaddle model scanner - support for Baidu's PaddlePaddle framework models (#172)
- feat: add ExecuTorch scanner - support for Meta's ExecuTorch mobile inference format (#171)
- feat: add TensorFlow SavedModel weight analysis - deep analysis of TensorFlow model weights (#138)
- ci: add GitHub Actions dependency caching - optimized CI pipeline performance (#183)
Fixed
- fix: optimize CI test performance for large blob detection (#184)
- fix: properly handle HuggingFace cache symlinks to avoid path traversal warnings (#178)
0.1.5 - 2025-06-20
Added
- feat: add cloud storage support - Direct scanning from S3, GCS, and other cloud storage (#168)
- feat: add JFrog Artifactory integration - Download and scan models from JFrog repositories (#167)
- feat: add JAX/Flax model scanner - Enhanced support for JAX/Flax model formats (#166)
- feat: add NumPy 2.x compatibility - Graceful fallback and compatibility layer (#163)
- feat: add MLflow model integration - Native support for MLflow model registry scanning (#160)
- feat: add DVC pointer support - Automatic resolution and scanning of DVC-tracked models (#159)
- feat: add nested pickle payload detection - Advanced analysis for deeply embedded malicious code (#153)
- feat: enhance SafeTensors scanner - Suspicious metadata and anomaly detection (#152)
- feat: add HuggingFace Hub integration - Direct model scanning from HuggingFace Hub URLs (#144, #158)
- feat: improve output formatting for better user experience (#143)
- feat: add PythonOp detection in ONNX - Critical security check for custom Python operations (#140)
- feat: add dangerous symlink detection - Identify malicious symbolic links in ZIP archives (#137)
- feat: add TFLite model scanner - Support for TensorFlow Lite mobile models (#103)
- feat: add asset inventory reporting - Comprehensive model asset discovery and cataloging (#102)
- feat: add Flax msgpack scanner - Support for Flax models using MessagePack serialization (#99)
- feat: add PMML model scanner - Support for Predictive Model Markup Language files (#98)
- feat: add header-based format detection - Improved accuracy for model format identification (#72)
- feat: add CycloneDX SBOM output - Generate Software Bill of Materials in standard format (#59)
- feat: add OCI layer scanning - Security analysis of containerized model layers (#53)
- test: add comprehensive test coverage for TFLite scanner (#165)
- perf: achieve 2074x faster startup - Lazy loading optimization for scanner dependencies (#129)
Changed
- perf: stop scanning when size limit reached for better performance (#139)
Fixed
- fix: reduce HuggingFace model false positives (#164)
- fix: reduce false positives for Windows executable detection in model files (#162)
0.1.4 - 2025-06-20
Added
- feat: add binary pattern validation - Executable signature and pattern analysis (#134)
- feat: refine import pattern detection - Enhanced detection of malicious imports (#133)
- feat: centralize security patterns with validation system (#128)
- feat: add unified scanner logging - Consistent logging across all scanner modules (#125)
- feat: add magic byte-based file type validation - Improved format detection accuracy (#117)
- feat: add centralized dangerous pattern definitions - Unified security rule management (#112)
- feat: add scan configuration validation - Input validation and error handling (#107)
- feat: add total size limit enforcement - Configurable scanning limits across all scanners (#106, #119)
- feat: enhance dill and joblib serialization support - Advanced security scanning for scientific computing libraries (#55)
- feat: add GGML format variants support for better compatibility (4c3d842)
- test: organize comprehensive security test assets with CI optimization (#45)
0.1.3 - 2025-06-17
Added
- feat: add security issue explanations - User-friendly 'why' explanations for detected threats (#92)
- feat: add modern single-source version management - Streamlined release process (#91)
- feat: add GGUF/GGML scanner - Support for llama.cpp and other quantized model formats (#66)
- feat: add ONNX model scanner - Security analysis for Open Neural Network Exchange format (#62)
- feat: add dill, joblib, and NumPy format support - Extended serialization format coverage (#60)
- feat: add comprehensive GGUF/GGML security checks - Advanced threat detection for quantized models (#56)
Changed
- chore: modernize pyproject configuration (#87)
- chore: refine package build configuration (#82)
Fixed
- fix: broaden ZIP signature detection (#95)
- fix: synchronize version between pyproject.toml and init.py to 0.1.3 (#90)
- fix: eliminate false positives in GPT-2 and HuggingFace models (#89)
0.1.2 - 2025-06-17
Added
- feat: add Biome formatter integration - Code quality tooling for JSON and YAML files (#79)
- feat: enable full scan for .bin files (#76)
- feat: add zip-slip attack protection - Prevent directory traversal attacks in ZIP archives (#63)
- feat: add SafeTensors scanner - Security analysis for Hugging Face's SafeTensors format (#61)
- feat: add dill pickle support - Extended pickle format security scanning (#48)
- feat: add CLI version command - Easy version identification for users (#44)
- feat: add weight distribution anomaly detector - Advanced backdoor detection through statistical analysis (#32)
- docs: optimize README and documentation for PyPI package distribution (#83)
Changed
- chore: update biome configuration to v2.0.0 schema (#85)
- chore: change errors → findings (#67)
Fixed
- fix: reduce PyTorch pickle false positives (#78)
- fix: log weight extraction failures (#75)
- fix: log debug issues at debug level (#74)
- fix: clarify missing data.pkl warning (#73)
- fix: clarify missing dependency error messages (#71)
- fix: change weight distribution warnings to info level (#69)
- fix: correct duration calculation (#68)
0.1.1 - 2025-06-16
Added
- feat: add multi-format .bin file support - Enhanced detection for various binary model formats (#57)
- feat: add PR title validation - Development workflow improvements (#35)
- feat: add manifest parser error handling - Better diagnostics for corrupted model metadata (#30)
- feat: change output label of ERROR severity to CRITICAL (#25)
Changed
- chore: replace Black, isort, flake8 with Ruff for faster linting and formatting (#24)
Fixed
- fix: treat raw .pt files as unsupported (#40)
- fix: avoid double counting bytes in zip scanner (#39)
- fix: mark scan result unsuccessful on pickle open failure and test (#29)
- fix: ignore debug issues in output status (#28)
- fix: use supported color for debug output (#27)
- fix: switch config keys to info and reduce false positives (#8)
- fix: reduce false positives for ML model configurations (#3)
0.1.0 - 2025-03-08
Added
- feat: add ZIP archive security analysis - Comprehensive scanning of compressed model packages (#15)
- feat: add stack_global opcode detection - Critical security check for dangerous pickle operations (#7)
- feat: add configurable exit codes - Standardized return codes for CI/CD integration (#6)
- feat: add core pickle scanning engine - foundation for malicious code detection in Python pickles (f3b56a7)
- docs: add AI development guidance - CLAUDE.md for AI-assisted development (#16)
- ci: add GitHub Actions CI/CD - Automated testing and security validation (#4)
Fixed
- style: improve code formatting and documentation standards (#12, #23)
- fix: improve core scanner functionality and comprehensive test coverage (#11)