Skip to content

Add SHA-256 hash pinning for .fun file loading#27

Merged
GiulsLu merged 2 commits intomainfrom
security/hash-pinning-fun-files
Feb 16, 2026
Merged

Add SHA-256 hash pinning for .fun file loading#27
GiulsLu merged 2 commits intomainfrom
security/hash-pinning-fun-files

Conversation

@tvogels
Copy link
Collaborator

@tvogels tvogels commented Feb 16, 2026

Summary

torch.jit.load deserializes arbitrary code via pickle, making it vulnerable to code execution if a .fun file is tampered with. This PR adds SHA-256 hash verification before calling torch.jit.load.

Changes

  • src/skala/functional/_hashes.py (new) — Pinned SHA-256 digests for skala-1.0.fun and skala-1.0-cuda.fun (from HuggingFace LFS OIDs).
  • src/skala/functional/load.pyTracedFunctional.load() accepts a keyword-only expected_hash parameter. When provided, the file is read into memory, hashed with SHA-256, and verified before torch.jit.load is called. Raises ValueError on mismatch.
  • src/skala/functional/__init__.pyload_functional("skala") looks up the pinned hash and passes it through. When SKALA_LOCAL_MODEL_PATH is used, hash verification is skipped with a logged warning.
  • examples/cpp/cpp_integration/download_model.py — Now passes the expected hash when loading downloaded models.
  • tests/test_hash_pinning.py (new) — 5 tests covering correct hash, wrong hash, opt-out (no hash), and file-path variants.

Security model

Load path Hash verified?
load_functional("skala") via HuggingFace ✅ Yes
download_model.py example ✅ Yes
TracedFunctional.load(path) (no hash passed) ⚠️ No (caller's responsibility)
SKALA_LOCAL_MODEL_PATH env var ⚠️ No (user-trusted, warning logged)

Thijs Vogels and others added 2 commits February 16, 2026 12:20
torch.jit.load deserializes arbitrary code via pickle, making it
vulnerable to code execution if a .fun file is tampered with. This
change verifies file integrity against pinned SHA-256 digests before
calling torch.jit.load.

- Add _hashes.py with known digests for microsoft/skala model files
- Add expected_hash parameter to TracedFunctional.load()
- Pass pinned hash from load_functional() for HF-downloaded models
- Skip verification for user-supplied SKALA_LOCAL_MODEL_PATH
- Add unit tests for hash verification (match, mismatch, opt-out)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tvogels tvogels requested a review from GiulsLu February 16, 2026 12:29
@tvogels tvogels self-assigned this Feb 16, 2026
Copy link
Contributor

@GiulsLu GiulsLu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified in a fresh conda env (cpu):

  • ✅ 5/5 new hash-pinning tests pass
  • ✅ 63/63 existing tests pass (no regressions)
  • ✅ Pre-commit (ruff, ruff-format, mypy) pass
  • ✅ Docs notebooks and README example run correctly

Looks good to me

@GiulsLu GiulsLu merged commit 8f60ad0 into main Feb 16, 2026
18 checks passed
@GiulsLu GiulsLu deleted the security/hash-pinning-fun-files branch February 16, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments