Skip to content

fix(security): pin HF model revision, cap JSONL line size, confine adapter reads to source root#110

Open
jugrajsingh wants to merge 3 commits into
samzong:mainfrom
jugrajsingh:fix/security-hardening
Open

fix(security): pin HF model revision, cap JSONL line size, confine adapter reads to source root#110
jugrajsingh wants to merge 3 commits into
samzong:mainfrom
jugrajsingh:fix/security-hardening

Conversation

@jugrajsingh

@jugrajsingh jugrajsingh commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Three independent supply-chain / hostile-input hardening fixes, bundled because they touch the same adapter surface and are small individually:

  1. Pin the embedding model revision. hf_hub::Repo::with_revision downloaded intfloat/multilingual-e5-small off the mutable main branch, so a compromised upstream push could silently swap the weights we load and embed. Pinned to the current main HEAD commit (614241f622f53c4eeff9890bdc4f31cfecc418b3, verified to still serve config.json/tokenizer.json/model.safetensors) via a named MODEL_REVISION const.
  2. Cap JSONL line size. Adapters previously read one JSONL line into memory unbounded; a corrupt or hostile session file with a single huge line could OOM the sync process. Lines over 32 MiB are now skipped with a warning instead of read in full, applied consistently across adapters via json_util.
  3. Confine adapter reads to their source root. New paths::confined_path(root, candidate) canonicalizes both the source root and a discovered/derived candidate path and rejects anything that escapes the root after following symlinks. Applied at every adapter file-open site (claude_code, copilot, cline, grok, antigravity, codex, pi, plus the direct walk+parse paths in cursor and gemini). A symlinked *.jsonl/*.json planted inside a tool's session directory, or a session dir whose transcript points outside the root, is now skipped with tracing::warn! rather than read verbatim into the searchable index; the rest of the scan continues. Root canonicalization is applied to both sides of the check so a symlinked dotfile root (e.g. ~/.claude -> elsewhere) still resolves correctly instead of false-rejecting everything under it.

All three are warn-and-skip, not hard failures — a single bad file degrades gracefully rather than aborting the sync.

Verification

  • cargo build, cargo fmt -- --check, cargo test --workspace — green.
  • 13 new tests covering: oversized-line skip + warning, symlink-escape rejection per adapter, canonicalized-root symlink dotfile case, and the pinned revision constant.

Test plan

  • JSONL line > 32 MiB → skipped with warning, rest of file still parses
  • Symlinked file inside a source root pointing outside it → skipped, scan continues
  • Symlinked root itself (e.g. dotfile symlink) → still indexes normally
  • Embedding download uses the pinned commit hash, not main

@jugrajsingh
jugrajsingh requested a review from samzong as a code owner July 18, 2026 09:54
hf_hub::Repo::with_revision downloaded intfloat/multilingual-e5-small
off the mutable "main" branch, so a compromised upstream push could
silently swap the weights we load. Pin to the current main HEAD commit
(614241f622f53c4eeff9890bdc4f31cfecc418b3, verified to still serve
config.json/tokenizer.json/model.safetensors) via a named
MODEL_REVISION const.
Add paths::confined_path(root, candidate), which canonicalizes both the
source root and a discovered/derived candidate path and rejects any
candidate that escapes the root after following symlinks. Apply it as a
skip-with-warn guard at every site where an adapter opens a file for
indexing: the collect_* entry builders for claude_code, copilot, cline,
grok, antigravity, codex, and pi, plus the direct walk+parse paths in
cursor (agent transcripts) and gemini.

A symlinked *.jsonl/*.json planted inside a tool's session directory, or a
session dir whose transcript points outside the root, previously had its
contents read verbatim into the searchable index. Such files are now
skipped with a tracing::warn! while the rest of the scan continues, per the
adapter contract. Sibling metadata reads that yield only directory strings
are unchanged.
@jugrajsingh
jugrajsingh force-pushed the fix/security-hardening branch from 17ff1a1 to f2c446d Compare July 21, 2026 07:30
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.

1 participant