Repository navigation
fix(security): the embedding model loads only safetensors; advisory paths stay unreachable - #938
Conversation
…aths stay unreachable macOS Intel has no wheel past torch 2.2.2 or cryptography 48.0.1, and Apple silicon before macOS 14 none past torch 2.11, so their 20 open Dependabot advisories cannot be closed by version on those platforms (uv --only-binary probe, 2026-11-07). The project keeps those platforms (owner, #740). The critical ones reach torch.load through a pickled checkpoint. The model is now built with model_kwargs use_safetensors=True, at load and in the background download: on the real pinned model it loads as before; a snapshot holding only a planted pytorch_model.bin is refused with OSError, torch.load is called 0 times and the payload never runs. A contract test names, per advisory, the function that reaches it (torch.jit, lstm_cell, save_pretrained, load_custom_generate, x509 verification, pkcs7, ...) and fails when mcp_server calls one; it also pins the model to one Hub commit, which keeps its config.json out of an attacker's hands (GHSA-29pf-2h5f-8g72).
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @cdeust's task in 2m 51s —— View job PR #938 review (1 of 3)
No Blockers. Both places that load the model, Three Notes, none needed before merge:
Verdict: approve |
Review 1 of 3: PR #938I ran five reviews (security, code quality, test coverage, documentation accuracy, performance) and found no Blockers.
Notes, no action before merge
Verdict: approve |
…isory paths stay unreachable Mutation gate (ADR-1122), run on #938: 4 survivors in trigger_background_model_download, on the lines of the child program. The test only matched a substring of that program; it now executes the program against a fake sentence_transformers and checks the exact call: name, revision, cache_folder and model_kwargs use_safetensors.
|
Claude finished @cdeust's task in 1m 15s —— View job PR #938 review (2 of 3)
No Blockers. The reworked test now runs the download child's own program against a fake Two Notes, none needed before merge:
Verdict: approve |
Review 2 of 3: PR #938Review 1 found no Blockers. I reviewed only the commit pushed after
Notes, no action before merge
Verdict: approve |
Problem
mainhas 20 open Dependabot advisories against torch, transformers, cryptography and setuptools. On Linux, Windows and Apple silicon macOS 14+,uv.lockalready resolves patched versions. The vulnerable versions are locked only for the platforms the project keeps (owner decision 2026-11-07, #740: x86_64 under Rosetta), and PyPI offers no patched wheel there. Probed withuv pip compile --only-binary :all:on 2026-11-07:Version bumps cannot close these advisories there, so this PR closes their paths instead.
Change
use_safetensors=True. The embedding model is built withmodel_kwargs={"use_safetensors": True}, both at load (embedding_model_lifecycle._construct_model) and in the background download child. transformers then loads only*.safetensorsand raises when the revision has none. A pickledpytorch_model.bin, thetorch.loadvector of the critical GHSA-53q9-r3pm-6pq6 and of GHSA-63cw-57p8-fm3p, is never read.Contract test.
tests_py/infrastructure/test_vulnerable_dependency_paths.py:mcp_server/calls it:torch.load,torch.jit,torch.ops.profiler,lstm_cell,pad_packed_sequence,unpack_sequence, quantized modules,mkldnn_max_pool2d,ctc_loss,save_pretrained,load_custom_generate,trust_remote_code=True,Trainer(, LightGlue, x509 verification /PolicyBuilder,pkcs7;config.jsoncannot be attacker-chosen (GHSA-29pf-2h5f-8g72, via_attn_implementation_internal);use_safetensors=True.cryptography is not imported by Cortex. It comes in through
pyjwt[crypto](MCP SDK auth), which uses neither the x509 verifier nor PKCS#7.Evidence
On the real pinned model (local macOS, torch 2.13, transformers 5.21, sentence-transformers 6.0.1):
SentenceTransformer(..., revision=<pin>, model_kwargs={"use_safetensors": True})loads and encodes ((1, 384)).model.safetensorsremoved and a plantedpytorch_model.bin(a pickle whose__reduce__runsos.system) is refused:OSError: Error no file named model.safetensors.torch.loadis called 0 times, and the payload's marker file is never created.Checks
ruff checkandruff format --checkpass on the touched files.scripts/check_craftsmanship.py: OK.Not in this PR
The x86_64 run itself is not reproduced: Rosetta is not installed on this host. The 20 alerts stay open; dismissing them as
vulnerable_code_not_usedwith this PR as the reason is the owner's call.