Skip to content

fix(protect): egress redirect re-screening + redaction case-sensitivity + IPv6-ULA over-match - #105

Merged
patchstackdave merged 2 commits into
mainfrom
fix/egress-redirect-rescreen-and-redaction-correctness
Aug 12, 2026
Merged

fix(protect): egress redirect re-screening + redaction case-sensitivity + IPv6-ULA over-match#105
patchstackdave merged 2 commits into
mainfrom
fix/egress-redirect-rescreen-and-redaction-correctness

Conversation

@patchstackdave

Copy link
Copy Markdown
Contributor

Three correctness fixes in the protect response/egress phases, from a review of the output-filtering surface. All contained; no API changes.

1. Egress: redirects weren't re-screened (SSRF via open redirect)

The guarded fetch screened only the initial URL, then delegated to native redirect: 'follow' — so a response that 302-redirects to an internal address (e.g. http://169.254.169.254/) reached it unchecked. Now we follow redirects ourselves with redirect: 'manual', screening every hop. Body is buffered once so 307/308 can replay it; 303 (and 301/302 on POST) rewrite to a bodyless GET; Authorization/Cookie are stripped on cross-origin hops; capped at 20 redirects; fail-open on un-normalizable input.

(The true fetch/undici connection pin — vs. resolve-and-screen — remains the separate roadmap item.)

2. Response redaction was case-sensitive while detection is case-insensitive

contains/stripos detection lowercases both sides, but the redactor masked with a case-sensitive split(literal). So a contains: "SECRET" rule detected secret yet masked nothing — the leak was served in the clear while telemetry reported a redaction. Now masks case-insensitively (escaped literal → gi regex), and encode escapes the actual matched span.

3. isInternalHost fc/fd prefix over-matched hostnames

The IPv6 ULA (fc00::/7) check fired on any hostname starting with fc/fd — e.g. fcm.googleapis.com — blocking legitimate egress in block mode. Now requires an actual IPv6 (: present).

Tests

tests/protect/correctness-fixes.test.ts (5 new): IPv6-ULA vs. hostname classification, case-insensitive redaction, redirect-to-internal blocked, redirect-to-allowed followed. Full suite 600 passed; typecheck clean.

🤖 Generated with Claude Code

…y, IPv6-ULA over-match

Three output-filtering / egress correctness fixes surfaced by a review of the response +
egress phases:

- egress: the guarded fetch only screened the initial URL and let native `redirect: follow`
  follow a 3xx to an internal address — an SSRF-via-open-redirect bypass (302 -> 169.254.169.254
  reached the metadata endpoint). Follow redirects ourselves with `redirect: manual`, screening
  every hop; buffer the body once so 307/308 can replay it, rewrite 303/POST -> GET, and strip
  Authorization/Cookie on cross-origin hops. Fail open on un-normalizable input.
- response redaction: `contains`/`stripos` detection is case-insensitive but the mask was
  case-sensitive, so a `contains: "SECRET"` rule detected `secret` yet masked nothing — the leak
  was served while telemetry reported a redaction. Mask case-insensitively.
- isInternalHost: the `fc`/`fd` IPv6-ULA prefix check fired on any hostname starting with those
  letters (e.g. fcm.googleapis.com), blocking legitimate egress in block mode. Require a colon
  (actual IPv6) before applying it.

600 tests pass (+5 new in tests/protect/correctness-fixes.test.ts); typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderbuds

coderbuds Bot commented Aug 12, 2026

Copy link
Copy Markdown

Comprehensive bug-fix with robust egress screening and thorough edge-case tests.

🎯 Quality: 100% Elite · 📦 Size: Medium

📈 This month: Your 49th PR — above team average · Averaging Excellent

See how your team is trending →

@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

Add edge cases for the correctness fixes: redirect method/body semantics (307 preserves
method+body, 303 rewrites to a bodyless GET), cross-origin Authorization stripping, the
max-redirects cap, caller redirect:'manual' passthrough (not followed), uppercase/bracketed
IPv6-ULA classification, and case-insensitive redaction of a secret in a response header as
well as the body. 13 tests in the file; full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@patchstackdave
patchstackdave merged commit 20fe4c3 into main Aug 12, 2026
4 checks passed
@patchstackdave
patchstackdave deleted the fix/egress-redirect-rescreen-and-redaction-correctness branch August 12, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants