Repository navigation
fix(cli): harden skillx add against large or hostile sources and credential leaks - #167
Merged
mrgoonie merged 4 commits intoOct 29, 2026
Merged
Conversation
…ential leaks - Clone with --filter=blob:none and fetch only the blobs discovery and the chosen skills need; read sizes from object headers before any content and read blobs in bounded batches instead of one 1 GiB buffer. - Refuse more than 1,000 SKILL.md candidates and skip a SKILL.md over 1 MiB unread; discovery parses front matter in chunks. - Keep URL credentials out of git's argv and .git/config: pass them as an origin-scoped http.extraHeader through GIT_CONFIG_* environment entries. - Remove the temporary clone on exit, SIGINT, SIGTERM and SIGHUP. - Redact userinfo up to the last @ of a URL and refuse, without echoing, a URL whose password holds a slash. - Resolve /tree/<ref>/<path> URLs against the remote's branches and tags so a branch name containing / is split correctly. Refs #163 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FL32runPrLpWgWsxUBpdCD
…g git - Turn http.followRedirects off whenever a URL credential is passed as a header: git matches http.<url>.extraHeader once and then sends it to the host a redirect leads to. A regression test runs a redirecting server in front of a real git http-backend on another host. - A git call killed by SIGINT, SIGTERM or SIGHUP removes every temporary clone and exits with 130, 143 or 129 instead of reporting a network error. - Refusals echo the input only when it holds no @. - Drop the promisor check (git sets it whenever --filter is passed) and say plainly that fetched blobs download whole, bounded by the per-call timeout. Refs #163 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FL32runPrLpWgWsxUBpdCD
A user's URL-scoped http.<url>.followRedirects=true outranked the unscoped http.followRedirects=false, so a token header could still follow a redirect. The guard is now keyed to the whole credential-free URL. A token URL that redirects fails as usage_error with a hint to use the final URL instead of a bare network_error. Refs #163 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FL32runPrLpWgWsxUBpdCD
…aude/admiring-ritchie-dnfgue # Conflicts: # packages/cli/src/commands/add.ts # packages/cli/src/lib/add/git-source.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #163. The
skillx addcode exists only on the branch of #120, which is still a draft, so this PR targetsfeat/skillx-add-commandand lands with #120.Changes
--filter=blob:none, and the listing comes from tree objects. Only the blobs that discovery and the chosen skills need are fetched, in one batch each.maxBuffer.SKILL.mdfiles is ausage_error. ASKILL.mdover 1 MiB is skipped without its content being read, and front matter is parsed in chunks.github:torvalds/linux/Documentationnow lists in under 3 s.Authorizationheader throughGIT_CONFIG_*environment entries, so it never appears in argv,.git/configor a credential helper.@of a URL./is refused without being echoed. So is any URL with an@that does not parse, or with an@in its path, and any refused input that contains@./tree/<ref>/<path>with a/in the branch name. The ref is resolved against the remote with an exact-patterngit ls-remote, and the longest matching branch or tag wins.Validation
pnpm typecheckpasses for every workspace package.pnpm exec vitest run packages/cli: 24 files, 276 tests pass. The new tests cover:SKILL.md;/;git http-backendon another host. This test fails, with the header leaked, whenhttp.followRedirects=falseis removed.pdf;/tree/cj/claude-api-resync/skills/pdfURL resolved to refcj/claude-api-resync;git clonewas running: exit 130, no envelope, temporary directory removed;/: refused with exit 2, not echoed;@) are fixed in 54fc381.Generated by Claude Code