Skip to content

fix(netguard): explain blocked address errors - #375

Open
0xkaushik-ai wants to merge 1 commit into
Infisical:mainfrom
0xkaushik-ai:fix/netguard-policy-error-305
Open

fix(netguard): explain blocked address errors#375
0xkaushik-ai wants to merge 1 commit into
Infisical:mainfrom
0xkaushik-ai:fix/netguard-policy-error-305

Conversation

@0xkaushik-ai

Copy link
Copy Markdown

Summary

Fixes #305.

Network-policy denials currently collapse into the same plain 502 bad gateway response as DNS, TLS, timeout, and connection failures. This makes intentional private-network deployments difficult to diagnose even though netguard already knows that it rejected the resolved address.

This change:

  • returns typed BlockedAddressError values from netguard, with coarse reasons for private/reserved ranges and permanently blocked metadata endpoints;
  • maps those errors to the standard broker JSON response with error: network_policy_blocked while preserving the existing HTTP 502 status;
  • records network_policy_blocked in request logs for both HTTP requests and WebSocket handshakes;
  • gives operators actionable allowlist/private-range guidance without returning the resolved IP to an untrusted proxy client;
  • documents the response in the security guide, agent protocol, and embedded agent skill.

Example response for an intentional private destination:

{
  "error": "network_policy_blocked",
  "message": "The target resolved to an address blocked by Agent Vault's network policy. If access to this private or reserved address is intentional, add it to AGENT_VAULT_NETWORK_ALLOWLIST or set AGENT_VAULT_ALLOW_PRIVATE_RANGES=true."
}

Metadata endpoints receive distinct guidance that they are always blocked.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / build

Test plan

  • Existing tests pass (go test ./...)
  • Added/updated tests for new behavior
  • Manual testing (automated proxy integration coverage described below)

Validation completed:

  • go test ./...
  • go test -race ./internal/netguard ./internal/mitm
  • go vet ./...
  • golangci-lint v2.11.0 run --new-from-rev=origin/main ./... (0 issues)
  • go build -trimpath
  • git diff --check

Regression coverage verifies:

  • private-range and metadata denials remain distinguishable through wrapped transport errors;
  • plain HTTP proxy requests return 502, X-Agent-Vault-Proxy-Error: true, and network_policy_blocked;
  • request-log rows persist the new error code;
  • WebSocket upstream dials return and log the same policy-specific error;
  • private-range guidance mentions the supported operator controls;
  • metadata guidance does not suggest an allowlist bypass.

Security checklist

  • No secrets or credentials in code
  • No new unauthenticated endpoints
  • Input validation on new API surfaces (no new API surface)
  • Checked for OWASP top 10 (injection, XSS, etc.)

Security invariants

  • Netguard's blocked ranges, allowlist precedence, and DNS-rebinding protections are unchanged.
  • Cloud metadata endpoints remain blocked even when private ranges are enabled or the address is allowlisted.
  • The resolved blocked IP remains available in server-side diagnostics but is intentionally omitted from the client response.
  • Existing clients continue to receive HTTP 502; the change adds a structured broker error and actionable message.
  • Non-policy upstream failures retain the existing plain bad gateway / upstream_error behavior.

Coordination

#374 also updates SafeDialContext to add multi-address fallback. This PR's typed error is designed to survive normal Go error wrapping (errors.As), including joined/wrapped dial errors. The two branches touch nearby netguard code, so I am happy to rebase promptly if #374 lands first.

@infisical-cla-app

infisical-cla-app Bot commented Aug 20, 2026

Copy link
Copy Markdown

CLA satisfied. All contributors have signed the current CLA. The cla/signed check is passing.

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes outbound network-policy denials distinguishable from other upstream failures without weakening netguard’s SSRF controls.

  • Adds typed private-range and metadata-endpoint rejection reasons while preserving existing address validation and blocking precedence.
  • Returns and logs network_policy_blocked for HTTP, HTTPS, and WebSocket requests.
  • Adds regression coverage and documents operator remediation without exposing resolved addresses to clients.

Confidence Score: 5/5

The PR appears safe to merge and preserves the existing SSRF boundary while improving policy-denial diagnostics.

The typed-error refactor leaves address classification and guarded dialing unchanged, both HTTP and WebSocket paths recognize the new error, and response and request-log mappings remain consistent without exposing blocked IP addresses.

Important Files Changed

Filename Overview
internal/netguard/netguard.go Introduces typed block reasons while preserving metadata precedence, private-range allowlist behavior, all-address DNS validation, and rebinding-safe direct IP dialing.
internal/mitm/forward.go Maps typed policy denials to the standard broker JSON response and matching request-log code while retaining generic handling for other upstream failures.
internal/mitm/websocket.go Applies the same policy-specific response and logging behavior to WebSocket upstream dial failures.
internal/mitm/forward_test.go Adds coverage for safe guidance, structured HTTP proxy responses, marker headers, and persisted policy error codes.
internal/mitm/websocket_test.go Verifies that WebSocket policy denials produce the structured response and matching emitted error code.
internal/netguard/netguard_test.go Verifies typed private-range and metadata errors while retaining existing block and allowlist invariants.

Reviews (1): Last reviewed commit: "fix(netguard): explain blocked address e..." | Re-trigger Greptile

@0xkaushik-ai

Copy link
Copy Markdown
Author

@infisical-cla-app I accepted the Infisical CLA using the @0xkaushik-ai GitHub account, but the cla/signed check is still showing the original action_required result from August 20. Could you please refresh or re-run the CLA check for this PR? Thank you.

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.

Provide a more descriptive error message when the IP address is in a private range

1 participant