Skip to content

docs(#233): add secure HTTP client guidance to AGENTS.md#277

Open
fullsend-ai-coder[bot] wants to merge 2 commits into
mainfrom
agent/233-secure-http-client-guidance
Open

docs(#233): add secure HTTP client guidance to AGENTS.md#277
fullsend-ai-coder[bot] wants to merge 2 commits into
mainfrom
agent/233-secure-http-client-guidance

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown

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

Post-script verification

  • Branch is not main/master (agent/233-secure-http-client-guidance)
  • Secret scan passed (gitleaks — c776c248ac9a91f10998ca7107e974a6c9d76514..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

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
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 10, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 1:05 PM UTC · Completed 1:05 PM UTC
Commit: c776c24 · View workflow run →

@guyoron1

Copy link
Copy Markdown
Owner

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 10, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:57 PM UTC · Completed 4:04 PM UTC
Commit: d8e3df7 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review

Findings

Medium

Low

  • [technical documentation accuracy] AGENTS.md:55 — The documentation instructs "Set Transport.Proxy = nil" and claims internal/fetch/fetch.go implements all five properties. While Go's stdlib confirms this is correct behavior ("If Proxy is nil or returns a nil *URL, no proxy is used"), fetch.go satisfies property [CNV-88172] Add test feature placeholder #3 implicitly via the zero-value of &http.Transport{} rather than an explicit Proxy: nil assignment. Adding an explicit field would make the canonical implementation self-documenting and prevent a future maintainer from accidentally switching to http.DefaultTransport (which sets Proxy: http.ProxyFromEnvironment).
    Remediation: 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.

  • [incomplete-reference] AGENTS.md:59 — 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 (it permits both http and https while blocking dangerous schemes like file, ftp, gopher).
    Remediation: Optionally change "HTTPS enforcement" to "HTTPS-only enforcement."

Previous run

Review

Verdict: 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 internal/fetch/fetch.go. All referenced source files (fetch.go, netutil/ip.go, security/ssrf.go) and symbols (FetchURL, FetchPolicy, CheckIP) exist and match their descriptions. Placement under "Go code" at ### heading level is consistent with the existing document hierarchy.

No security concerns, no scope creep, no injection patterns.

Minor notes (non-blocking)

# File Observation
1 AGENTS.md The doc says to validate IPs "with netutil.CheckIP" but fetch.go (the referenced canonical implementation) actually calls netutil.IsInternal — a thin wrapper around CheckIP. Both are correct; CheckIP is arguably better guidance for new code since it returns a reason string. A developer grepping fetch.go for CheckIP will find no hits.
2 AGENTS.md Property 3 advises "Set Transport.Proxy = nil" explicitly. fetch.go achieves the same result via Go's zero value (a fresh &http.Transport{} has nil Proxy). The explicit-nil guidance is the more defensive practice — just noting that the reference implementation doesn't literally match the guideline text.
3 AGENTS.md The closing paragraph references ssrf.go as the "URL-level SSRF validator" in the same section that mandates HTTPS-only. ssrf.go's ValidateURL permits http:// (it only blocks dangerous schemes like file://, gopher://). The doc correctly attributes all five properties to fetch.go, not ssrf.go, so this isn't a contradiction — but readers may benefit from a parenthetical clarifying that ssrf.go handles host/IP validation while HTTPS enforcement is in fetch.go.

Protected paths detected — this PR modifies files under one or more
protected paths. The review agent cannot approve PRs that touch these paths.
A human reviewer must approve this PR.

Protected files in this PR:

  • AGENTS.md

Labels: PR adds security-focused documentation to AGENTS.md

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment documentation Improvements or additions to documentation security labels Jul 10, 2026
@guyoron1

Copy link
Copy Markdown
Owner

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 10, 2026

Copy link
Copy Markdown
Author

🤖 Finished Fix · ✅ Success · Started 5:43 PM UTC · Completed 5:52 PM UTC
Commit: d8e3df7 · View workflow run →

…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
@fullsend-ai-coder

Copy link
Copy Markdown
Author

🔧 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):

  1. fetch.go uses netutil.IsInternal, not CheckIP (AGENTS.md): Updated property 1 to mention both netutil.IsInternal (used by the canonical fetch.go implementation) and netutil.CheckIP, so developers grepping the reference implementation find the function
  2. ssrf.go permits http:// but doc implies it enforces HTTPS (AGENTS.md): Clarified closing paragraph: ssrf.go handles host/IP/scheme validation while HTTPS enforcement lives in fetch.go, preventing reader confusion about where each property is implemented

Disagreed (1):

  1. Transport.Proxy = nil vs zero-value behavior: The explicit-nil guidance is the more defensive practice for new code, even though fetch.go relies on Go's zero value. Keeping the doc as-is gives better guidance for developers writing new HTTP clients.

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 10, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:53 PM UTC · Completed 6:05 PM UTC
Commit: d8e3df7 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread AGENTS.md

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Comment thread AGENTS.md
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`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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."

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation requires-manual-review Review requires human judgment security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RTK+Ponytail] Add AGENTS.md guidance for secure HTTP client construction in Go

1 participant