docs(#233): add secure HTTP client guidance to AGENTS.md#277
docs(#233): add secure HTTP client guidance to AGENTS.md#277fullsend-ai-coder[bot] wants to merge 2 commits into
Conversation
Add a "Secure HTTP clients" subsection under "Go code" documenting the five required security properties for any new http.Client that fetches external URLs: 1. SSRF-safe dialer with DNS pre-resolution and IP validation via netutil.CheckIP 2. HTTPS-only with redirect blocking or scheme validation 3. Transport.Proxy = nil to prevent proxy-based redirection 4. Explicit timeout (30s default) — never http.DefaultClient 5. io.LimitReader for response bodies (10 MB default) References internal/fetch/fetch.go (FetchURL/FetchPolicy), internal/netutil/ip.go (CheckIP), and internal/security/ssrf.go (SSRFValidator) as the canonical implementations. Closes #233
|
🤖 Finished Review · ❌ Failure · Started 1:05 PM UTC · Completed 1:05 PM UTC |
|
/fs-review |
|
🤖 Finished Review · ✅ Success · Started 3:57 PM UTC · Completed 4:04 PM UTC |
ReviewFindingsMedium
Low
Previous runReviewVerdict: Approve Well-scoped docs PR that adds actionable secure-HTTP-client guidance to AGENTS.md, directly addressing issue #233. The five documented security properties are technically accurate and consistent with the canonical implementation in No security concerns, no scope creep, no injection patterns. Minor notes (non-blocking)
Labels: PR adds security-focused documentation to AGENTS.md |
|
/fs-fix |
|
🤖 Finished Fix · ✅ Success · Started 5:43 PM UTC · Completed 5:52 PM UTC |
…TTP guidance - Property 1: mention both netutil.IsInternal (used by fetch.go) and netutil.CheckIP so developers can find the function in the reference impl - Closing paragraph: clarify that ssrf.go handles host/IP/scheme validation while HTTPS enforcement lives in fetch.go Addresses review feedback on #277
🔧 Fix agent — iteration 1 (human-triggered)Addressed 2 of 3 non-blocking review observations (IP validation function reference and SSRF validator role clarification). Disagreed with 1 (Transport.Proxy nil guidance is correct as-is for new code). Fixed (2):
Disagreed (1):
Tests: passed Updated by fullsend fix agent |
|
🤖 Finished Review · ✅ Success · Started 5:53 PM UTC · Completed 6:05 PM UTC |
|
|
||
| 1. **SSRF-safe dialer.** Use a custom `DialContext` that pre-resolves DNS, validates every resolved IP with `netutil.IsInternal` or `netutil.CheckIP` (`internal/netutil/ip.go`), and dials the validated IP directly (pinning against DNS rebinding). Reject loopback, private (RFC 1918), link-local, and other reserved addresses. Fail closed — if DNS resolution fails or returns no addresses, do not connect. | ||
| 2. **HTTPS only.** Reject `http://` URLs at parse time. Block redirects entirely (`CheckRedirect` returning `http.ErrUseLastResponse`) or validate that every redirect target also uses HTTPS. | ||
| 3. **No proxy.** Set `Transport.Proxy = nil` to prevent the client from honoring `HTTP_PROXY`/`HTTPS_PROXY` environment variables, which an attacker could use to redirect traffic. |
There was a problem hiding this comment.
[low] technical documentation accuracy
The documentation instructs "Set Transport.Proxy = nil" and claims internal/fetch/fetch.go implements all five properties. While the guidance is correct (Go docs: "If Proxy is nil or returns a nil *URL, no proxy is used"), fetch.go satisfies this property implicitly via zero-value rather than an explicit Proxy: nil assignment. Adding the explicit field would make the canonical implementation self-documenting.
Suggested fix: Add Proxy: nil to the Transport literal in fetch.go, or reword the guidance to clarify that constructing a new http.Transport (rather than cloning http.DefaultTransport) inherently disables proxy usage.
| 4. **Explicit timeout.** Set `http.Client.Timeout` (30 s default). Never use `http.DefaultClient` or `http.Get` — both have no timeout. | ||
| 5. **Response size limit.** Wrap the response body with `io.LimitReader` (10 MB default) to prevent memory exhaustion from malicious or unexpectedly large responses. | ||
|
|
||
| See `internal/fetch/fetch.go` for the canonical SSRF-hardened HTTP client (`FetchURL` / `FetchPolicy`) that implements all five properties. See `internal/netutil/ip.go` for the `CheckIP` implementation and `internal/security/ssrf.go` for host/IP/scheme validation (note: HTTPS enforcement is in `fetch.go`, not `ssrf.go`). |
There was a problem hiding this comment.
[low] incomplete-reference
The parenthetical "(note: HTTPS enforcement is in fetch.go, not ssrf.go)" is factually correct but could be marginally clearer as "HTTPS-only enforcement" since ssrf.go does contain scheme validation logic (permits both http and https while blocking dangerous schemes).
Suggested fix: Optionally change "HTTPS enforcement" to "HTTPS-only enforcement."
Add a "Secure HTTP clients" subsection under "Go code" documenting the five required security properties for any new http.Client that fetches external URLs:
via netutil.CheckIP
References internal/fetch/fetch.go (FetchURL/FetchPolicy), internal/netutil/ip.go (CheckIP), and internal/security/ssrf.go (SSRFValidator) as the canonical implementations.
Closes #233
Post-script verification
agent/233-secure-http-client-guidance)c776c248ac9a91f10998ca7107e974a6c9d76514..HEAD)