Skip to content

fix(web): bound the fetch SSRF pre-flight DNS lookup - #6852

Merged
Hmbown merged 1 commit into
codewhale-hq:mainfrom
asto18089:upstream/web-fetch-bounds
Oct 5, 2026
Merged

Hmbown merged 1 commit into
codewhale-hq:mainfrom
asto18089:upstream/web-fetch-bounds

Conversation

@asto18089

Copy link
Copy Markdown
Contributor

Summary

The SSRF pre-flight in validate_fetch_target resolved the target host with an unbounded tokio::net::lookup_host. The lookup runs before the guarded request — and once per redirect — so a wedged resolver stalled the fetch tool past its own 60s HARD_MAX_TIMEOUT envelope with no recovery.

Bound the pre-flight at 10s (DNS_PREFLIGHT_TIMEOUT). A hung resolver now fails the pre-flight with an explicit "timed out resolving host" permission error; the DNS-failure error path and message are unchanged, and the existing resolution-failure regression still holds. Literal-IP and localhost targets don't resolve and are unaffected. A test pins the bound below the fetch hard cap so the two constants cannot drift.

Testing

  • cargo test -p codewhale-tui --lib web::guard
  • cargo clippy -p codewhale-tui --all-targets --all-features --locked

Disclosure: the timeout branch itself is not exercised by a test (that would require intercepting OS DNS); coverage is the constant-relationship pin plus the preserved, still-tested resolution-failure path.

Adapted from the Pinvou fork's timeout audit (Pinvou/CodeWhale d349f2537, the DNS pre-flight slice only).

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • No CHANGELOG.md changes

The SSRF pre-flight in `validate_fetch_target` resolves the target host
with an unbounded `tokio::net::lookup_host`. The lookup runs before the
guarded request — and once more per redirect — so a wedged resolver
stalled the fetch tool past its own 60s HARD_MAX_TIMEOUT envelope with
no way for the caller to recover.

Bound the pre-flight resolution at 10 seconds. A resolver that does not
answer in time now fails the pre-flight with an explicit "timed out
resolving host" permission error instead of stalling the tool; the
documented request hard cap itself is unchanged. A test pins the bound
below the fetch hard cap, and the existing unresolved-host regressions
cover the preserved DNS-failure error path.

Signed-off-by: asto <asto18089@126.com>
@asto18089
asto18089 requested a review from Hmbown as a code owner October 5, 2026 11:51
@github-actions github-actions Bot added the contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm label Oct 5, 2026
@Hmbown
Hmbown merged commit 5de2a33 into codewhale-hq:main Oct 5, 2026
1 check passed
@Hmbown Hmbown added this to the v0.10.1 milestone Oct 5, 2026
Hmbown pushed a commit that referenced this pull request Oct 5, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants