harden(org-external): token via http.extraHeader, .complete cache marker, ref '..' deny, naming cleanup #107
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/external-resolver-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Self-review of molecule-core#105 + #106 (the
!externalresolver chain) surfaced 3 real correctness/security gaps and 2 readability nits. Fixes all four in one PR since they're the same file's hardening.(1) Token leakage — fixed
Before: clone URLs built with auth in userinfo (
https://oauth2:TOKEN@host/repo.git). Two leak paths:.git/config.cmd.CombinedOutput().After: clone URL has no userinfo. Auth layered via
-c http.extraHeader=Authorization: token ...(sent per-request, not persisted).redactToken()pass over any error string as belt-and-braces.Tradeoff: token now visible in
ps auxfor the duration of the git child process (same as before via the env var), but not in persistent state.(2) Cache-validity footgun — fixed
Before: cache-hit was
cacheDir/.git exists. A clone interrupted after.gitcreation but before content finished would leave a partially-written cache that subsequent imports treated as hit → stale content forever, no self-heal.After: cache-hit requires a
.completemarker file written only AFTER successful clone+rename. Partially-written cache is treated as cache-miss and re-fetched cleanly (afterRemoveAllto avoid blocking the new clone'smkdir).(3) Ref
..deny — fixedBefore:
safeRefPattern ^[a-zA-Z0-9_./-]+$allowed..as a substring. Git itself rejects most such refs, but defense-in-depth: don't depend on the downstream tool's validation at the input boundary.After: explicit
strings.Contains(ref.Ref, "..")check.(4) Naming cleanup
rewriteFilesDirAndIncludes()→rewriteFilesDir(). Function only rewritesfiles_dirscalars;!includerewriting was removed during PR-A development (double-prefix bug). Old name was misleading. Docstring now explicitly explains why!includepaths are NOT rewritten.buildAuthedURL()(replaced bybuildExternalCloneURL+authConfigArgssplit).shortHash()(replaced byos.MkdirTemp).crypto/sha1,encoding/hex,fmt._ = fmt.Sprintin integration test.New tests
TestGitFetcher_RejectsRefWithDoubleDot— defense-in-depth on ref input.TestGitFetcher_CacheValidatedByCompleteMarker— partial cache → re-fetch.Verified locally (2026-05-08)
Refs
/code-review-and-quality2026-05-08 + 'fix all'LGTM. Three real fixes (token persistence, partial-cache permanence, defense-in-depth ref validation) caught by structured five-axis self-review. The http.extraHeader approach is the right shape — tradeoff documented honestly. Test additions cover both new behaviors. Naming cleanup is overdue.