Repository navigation
Wire safe-fetch into forge fetches (SHIP_SAFE_FETCH, shadow by default) - #44
Merged
Merged
Conversation
…default) Adds src/forge-egress.ts: production pinned fetch (undici Agent whose connect.lookup returns the validated address), operator allow-list (SHIP_SAFE_FETCH_ALLOW) for self-hosted forges, and a forge fetch used as the default in git.ts and forge-state.ts. Default is shadow: the request is untouched and what enforcement would refuse is logged once per host and reason. SHIP_SAFE_FETCH=on enforces and validates every redirect hop; =off disables the check entirely. Tested on a real loopback socket (refused by default, reachable when explicitly allowed, connection pinned against a rebinding resolver). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VqsBNqvaWezf1DwQrAnVgX
Keeps the forge-egress default fetch and the inline comments option from the finding continuity change in forge-state.ts. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VqsBNqvaWezf1DwQrAnVgX
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.
Changes
src/forge-egress.ts: production pinned fetch (undiciAgentwhoseconnect.lookupreturns the validated address; hostname kept for SNI/Host), operator allow-list,decideEgress, andforgeFetch.src/git.tsandsrc/forge-state.ts: the DEFAULT fetch (?? fetch/= fetch) becomesforgeFetch. InjectedfetchImplpaths are untouched.forgeFetchcallsglobalThis.fetchat call time, so tests that replace it still work.SHIP_SAFE_FETCH: unset/shadow(default) leaves the request untouched and logs once per host+reason what enforcement would refuse (check runs beside the request, never in front of it);onenforces (refuse, validate every redirect hop, connect to the validated address only, credentials stripped off-origin);offdisables everything.SHIP_SAFE_FETCH_ALLOW=host1,host2:3000,[::1]:8080: listed hosts are trusted by name (private addresses, http, any/listed port, single-label names). Metadata and link-local answers stay refused even for listed hosts.Checks
pnpm run lintclean;pnpm test1868/1868 on dist; webpnpm test156/156,pnpm run buildok.src/forge-egress.test.ts, including a REAL loopback http server: refused under the default policy (server sees zero requests), reachable with an explicit allow, connection pinned against a rebinding resolver (resolver called once, Host header is the name),pinnedFetchto an unresolvable name, redirect hop refusal,retrieveUntrustedwith the production fetch, and the git.ts call path (findOpenPullRequest) refused when enforcing.connect.lookupdo real DNS fails 2 pin tests.scripts/*.test.mjshas 3 failures (matrix, pj-b-deploy-recovery grader, committed report totals). They fail identically on origin/main without this change.Not verified / still open
Requestinputs are rejected when enforcing (forge code only passes strings).🤖 Generated with Claude Code
https://claude.ai/code/session_01VqsBNqvaWezf1DwQrAnVgX
Generated by Claude Code