Harden opt-in lifecycle hooks (SSRF, cache poisoning, symlink overwrite, data loss)#294
Open
bill143 wants to merge 1 commit into
Open
Harden opt-in lifecycle hooks (SSRF, cache poisoning, symlink overwrite, data loss)#294bill143 wants to merge 1 commit into
bill143 wants to merge 1 commit into
Conversation
…te, data loss
sdd-cache-{pre,post}.sh:
- Add url_is_safe() allowlist: require https://, reject loopback/RFC1918/
link-local (incl. 169.254 metadata)/CGNAT/IPv6-literal/*.internal hosts.
- Drop `curl -L`; use --proto =https --max-redirs 0 (kills redirect SSRF).
- Enforce TTL cap (SDD_CACHE_MAX_AGE, default 24h) before serving on 304.
- Create cache dir 0700 under umask 077 so entries are not world-readable.
simplify-ignore.sh:
- Reject symlinks at Read entry; re-verify regular-file target before every
write-back (Read/Edit/Write/Stop) to close TOCTOU/arbitrary-overwrite.
- trap-guarded atomic rewrite: restore from backup on unexpected exit so an
abort can never leave the file half-placeholdered with the backup consumed.
- Remove undeclared `perl` dependency (pure-shell trailing-newline trim).
- Normalize path before hashing file_id (C:\x and /c/x map to one identity).
Existing tests pass (21/21 simplify-ignore, session-start); added SSRF guard
smoke test (15/15).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
|
This is security-sensitive by nature, so it gets a careful pass rather than a quick merge. SSRF and cache-poisoning hardening on the lifecycle hooks is worth doing, but these hooks run on every session start for every user, so I want to read the change against the existing no-jq fallback and the payload test before anything lands. Give me the time to go through it properly, and thanks for taking the hooks seriously. |
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.
What
Hardens the three opt-in lifecycle hooks (
sdd-cache-pre.sh,sdd-cache-post.sh,simplify-ignore.sh) against security and data-integrity issues surfaced during a review. These hooks are not enabled byhooks/hooks.json(which only wiressession-start.sh), so this affects users who manually enable the WebFetch cache or simplify-ignore per the docs.session-start.shis unchanged (reviewed clean).Why / findings addressed
curl -L "$URL"on an unvalidated, redirect-following URL fires automatically on every WebFetch; a 302 can reach169.254.169.254,localhost, RFC1918url_is_safe()allowlist + drop-L(--proto =https --max-redirs 0)304re-serves the cached body forever as "unchanged"fetched_at(SDD_CACHE_MAX_AGE, default 24h)0700, files0600viaumask 077cat > "$target"on untrustedfile_pathfollows symlinks; session-long TOCTOUset -ecan leave a half-placeholdered file after the backup was consumedtrap-guarded restore-from-backup around the rewriteperldependency — abort point on minimal Git BashC:\xvs/c/xhash to different IDs → stale restorefile_idHow it's verified
bash -nclean on all four hooks.simplify-ignore-test.sh,session-start-test.shOK.user@hostuserinfo trick, and correctly-allowed public hosts incl. just-outside-range172.15.0.1).Notes / open design decisions (flagged, not silently chosen)
curl --resolve), which adds platform variance on Git Bash. Left as a follow-up; relies on WebFetch's own egress controls for that case.--max-redirs 0trades cache hit-rate on redirecting origins for SSRF safety. A middle ground (--max-redirs N --proto-redir =https+ re-validating%{url_effective}) is possible if hit-rate matters.cat >kept (notmv) to preserve inode/permissions as the original intended; atomicity-of-outcome is provided by thetrapinstead.file_idchange orphans any pre-existing cache entries from the old scheme (one-time; Stop already tolerates orphans).Happy to split this into per-file PRs or adjust any of the above. Related findings filed as an issue for tracking.
🤖 Generated with Claude Code