fix(security): SSRF sub-resource + fail-closed, webhook 500, trusted rate-limit IP#2
Merged
Merged
Conversation
…rate-limit IP Post-merge follow-ups from the PR #1 review (3 sub-agents + verification). scan-service SSRF (scanner.ts -> request-guard.ts): - Validate EVERY http(s) request -- main nav, redirect hops, AND sub-resources -- via DNS-resolving checkHostSafety, not just literal-IP hosts. Closes the hostname sub-resource SSRF hole (e.g. an <img src> to a name resolving to a private/metadata IP). - Fail CLOSED: guard errors now abort the request (was req.continue()). - Pass through non-network schemes (data:/blob:). Per-scan host cache. - Extracted to request-guard.ts; 7 offline unit tests. webhook (route.ts): - Return 500 on non-23505 insert failures so Stripe retries; a 200 silently dropped a paid report. Pre-insert lookup + 23505 guard make retries safe. rate-limit (client-ip.ts + all 6 routes): - Derive client IP from x-real-ip / last XFF hop, not the spoofable left-most x-forwarded-for token. Verified: scan-service tsc clean + 59/59 tests; app tsc --noEmit clean. DNS-rebind IP-pinning + coupon max_uses atomicity tracked as follow-ups.
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.
Summary
Post-merge security follow-ups from the PR #1 review (3 independent sub-agents + orchestrator verification). All fixes verified locally.
scan-service SSRF —
scanner.ts→ newrequest-guard.tscheckHostSafety— closes the hostname sub-resource SSRF hole (only literal IPs were blocked before).abort()instead ofcontinue().data:/blob:; per-scan host cache.webhook idempotency —
app/app/api/webhook/route.ts23505insert failures so Stripe retries. A 200 silently dropped a paid report. The pre-insert lookup +23505guard make retries safe.rate-limit key —
app/lib/client-ip.ts+ 6 routesx-real-ip/ last XFF hop, not the spoofable left-mostx-forwarded-fortoken.Test plan
scan-service:tscclean, 59/59 vitest (7 newrequest-guardtests)app:tsc --noEmitcleanDeliberately deferred (need E2E I can't run blind)
--host-resolver-rules/CDP peer-IP + a rebind harness.max_usesatomicity — atomic RPC + caller rejection; touches the Stripe path.report-statusdroppingemail— UI-coupled.