Documentation
¶
Overview ¶
Package networking provides utilities for network operations, such as finding available ports and checking network connectivity.
Index ¶
- Constants
- Variables
- func AddressReferencesPrivateIp(address string) error
- func FindAvailable() int
- func FindOrUsePort(port int) (int, error)
- func GetProcessOnPort(port int) (int, error)
- func IsAvailable(port int) bool
- func IsHTTPError(err error, statusCode int) bool
- func IsLocalhost(host string) bool
- func IsLoopbackHost(host string) bool
- func IsPreRegisteredClient(clientID string) bool
- func IsPrivateIP(ip net.IP) bool
- func IsURL(input string) bool
- func NewHTTPError(statusCode int, url, message string) error
- func NewPrivateIPBlockingDialContext() func(ctx context.Context, network, addr string) (net.Conn, error)
- func ParsePortSpec(portSpec string) (string, int, error)
- func SameHostRedirectPolicy() func(req *http.Request, via []*http.Request) error
- func TargetIsPrivate(ctx context.Context, rawURL string) bool
- func ValidateCallbackPort(callbackPort int, clientID string) error
- func ValidateEndpointURL(endpoint string) error
- func ValidateEndpointURLWithInsecure(endpoint string, insecureAllowHTTP bool) error
- func ValidateHTTPSURL(rawURL string) error
- func ValidateIssuerURL(rawURL string) error
- func ValidateLoopbackAddress(addr string) error
- type FetchOption
- type FetchResult
- type HTTPClient
- type HTTPError
- type HttpClientBuilder
- func (b *HttpClientBuilder) Build() (*http.Client, error)
- func (b *HttpClientBuilder) WithCABundle(path string) *HttpClientBuilder
- func (b *HttpClientBuilder) WithDisableKeepAlives(disable bool) *HttpClientBuilder
- func (b *HttpClientBuilder) WithInsecureAllowHTTP(allow bool) *HttpClientBuilder
- func (b *HttpClientBuilder) WithPrivateIPs(allow bool) *HttpClientBuilder
- func (b *HttpClientBuilder) WithTimeout(timeout time.Duration) *HttpClientBuilder
- func (b *HttpClientBuilder) WithTokenFromFile(path string) *HttpClientBuilder
- type ValidatingTransport
Constants ¶
const ( // MinPort is the minimum port number to use MinPort = 10000 // MaxPort is the maximum port number to use MaxPort = 65535 // MaxAttempts is the maximum number of attempts to find an available port MaxAttempts = 10 )
const (
// ErrPrivateIpAddress is the error returned when the provided URL redirects to a private IP address
ErrPrivateIpAddress = "the provided URL redirects to a private IP address, which is not allowed"
)
const HttpScheme = "http"
HttpScheme is the HTTP scheme
const HttpTimeout = 30 * time.Second
HttpTimeout is the timeout for outgoing HTTP requests
const HttpsScheme = "https"
HttpsScheme is the HTTPS scheme
const MaxRedirects = 10
MaxRedirects bounds how many HTTP redirects an SSRF-guarded client follows before giving up. Matches the cap used by the transparent proxy data path.
Variables ¶
var ErrRedirectRefused = errors.New("redirect refused")
ErrRedirectRefused is wrapped by SameHostRedirectPolicy when it declines to follow a redirect, so callers can match it with errors.Is.
Functions ¶
func AddressReferencesPrivateIp ¶ added in v0.1.1
AddressReferencesPrivateIp returns an error if the address references a private IP address
func FindOrUsePort ¶
FindOrUsePort checks if the provided port is available or finds an available port if none is provided. If port is 0, it will find an available port. If port is not 0, it will check if the port is available. Returns the selected port and an error if any.
func GetProcessOnPort ¶ added in v0.11.1
GetProcessOnPort returns the PID of the process listening on the given TCP port. Returns 0 if the port is free or if the holder cannot be determined. Uses gopsutil which provides cross-platform support (Linux: /proc, Windows: GetExtendedTcpTable, Darwin/FreeBSD: lsof).
func IsHTTPError ¶ added in v0.7.0
IsHTTPError checks if an error is an HTTPError with the specified status code. If statusCode is 0, it matches any HTTPError.
func IsLocalhost ¶ added in v0.2.4
IsLocalhost checks if a host is a loopback address (for development). The canonical implementation lives in pkg/oauthproto.IsLoopbackHost; this function is a thin wrapper that preserves backward compatibility for all callers in this package and beyond.
func IsLoopbackHost ¶ added in v0.25.0
IsLoopbackHost reports whether the Host header value refers to a loopback address. It is intended for DNS-rebinding guards on loopback-only listeners. It accepts the hostname "localhost" (case-insensitive), any 127.x.x.x address, and the IPv6 loopback ::1. Both plain-host and host:port forms are accepted. Hostnames other than "localhost" are NOT resolved.
func IsPreRegisteredClient ¶ added in v0.3.9
IsPreRegisteredClient determines if the OAuth client is pre-registered (has client ID)
func IsPrivateIP ¶ added in v0.11.3
IsPrivateIP reports whether ip is a private, loopback, link-local, unspecified, or otherwise reserved/non-public address.
NAT64-translated addresses are evaluated by the IPv4 address they embed: a NAT64 address whose low 32 bits map to a private/link-local IPv4 (e.g. 64:ff9b:1::a9fe:a9fe -> 169.254.169.254, the cloud metadata endpoint) is treated as private, because behind a NAT64 gateway it reaches exactly that internal IPv4, while NAT64 addresses embedding a genuinely public IPv4 remain allowed. This /96 decoding covers the well-known 64:ff9b::/96 (RFC 6052) and the 64:ff9b:1::/96 sub-prefix of the RFC 8215 local-use range; the rest of 64:ff9b:1::/48 uses a non-/96 embedding that cannot be decoded from the address alone and is blocked wholesale (see privateIPBlocks).
func NewHTTPError ¶ added in v0.7.0
NewHTTPError creates a new HTTP error.
func NewPrivateIPBlockingDialContext ¶ added in v0.31.0
func NewPrivateIPBlockingDialContext() func(ctx context.Context, network, addr string) (net.Conn, error)
NewPrivateIPBlockingDialContext returns a DialContext that refuses to connect to private, loopback, or link-local addresses. The check runs after DNS resolution on the address actually being dialed, so it also defends against DNS rebinding and is re-applied on every redirect hop. Pair it with Transport.DisableKeepAlives so a pooled connection cannot skip the check on a later request.
Use this on clients that fetch a URL derived from untrusted input when the operator-configured target is public; SameHostRedirectPolicy is the redirect-following counterpart.
func ParsePortSpec ¶ added in v0.13.0
ParsePortSpec parses a port specification string in the format "hostPort:containerPort" or just "containerPort". Returns the host port string and container port integer. If only a container port is provided, a random available host port is selected.
func SameHostRedirectPolicy ¶ added in v0.31.0
SameHostRedirectPolicy returns a value for http.Client.CheckRedirect that follows only same-host redirects, refuses HTTPS-to-HTTP downgrades, and caps the chain at MaxRedirects.
Any client that fetches a URL derived from an untrusted remote server — auth discovery probes, RFC 9728 resource-metadata fetches, OIDC issuer discovery — must install this. Validating only the originally-supplied URL is not enough: a malicious server can return a 30x that points the request at an internal address (cloud IMDS, RFC1918 services), and the host-side client would follow it (CWE-918). Restricting redirects to the same host as the original request keeps the request on the endpoint the operator actually configured.
This mirrors the data-plane guard in pkg/transport/proxy/transparent (followRedirects); keep the two policies in sync.
func TargetIsPrivate ¶ added in v0.31.0
TargetIsPrivate reports whether the host in rawURL refers to — or resolves to — a private, loopback, or link-local address. It is used to detect when an operator has deliberately pointed ToolHive at an internal target, so that discovery fetches derived from untrusted server input may also be allowed to reach internal addresses for that deployment.
IP literals and "localhost" are classified without DNS. Hostnames are resolved and reported private if ANY resolved address is private. Unparsable input or resolution failure returns false (treat as public — the SSRF guard then stays engaged, failing secure).
func ValidateCallbackPort ¶ added in v0.3.9
ValidateCallbackPort validates that the specified callback port is valid and available. It checks that the port is within the valid range (1-65535) and, for pre-registered clients (with clientID), it returns an error if the port is not available.
func ValidateEndpointURL ¶ added in v0.2.4
ValidateEndpointURL validates that an endpoint URL is secure
func ValidateEndpointURLWithInsecure ¶ added in v0.4.2
ValidateEndpointURLWithInsecure validates that an endpoint URL is secure, allowing HTTP if insecureAllowHTTP is true WARNING: This is insecure and should NEVER be used in production
func ValidateHTTPSURL ¶ added in v0.25.0
ValidateHTTPSURL checks that rawURL is a valid URL using the https scheme. Unlike ValidateEndpointURL, no localhost exception is made — HTTPS is always required (suitable for gateway URLs and other production endpoints).
func ValidateIssuerURL ¶ added in v0.25.0
ValidateIssuerURL validates that an OIDC issuer URL is well-formed and uses HTTPS. HTTP is permitted only for localhost (development). Per OIDC Core Section 3.1.2.1 and RFC 8414 Section 2, the issuer MUST use the "https" scheme.
func ValidateLoopbackAddress ¶ added in v0.25.0
ValidateLoopbackAddress returns an error if addr (a host:port string) does not contain a literal loopback IP address. Both IPv4 (127.x.x.x) and IPv6 (::1) loopback addresses are accepted. Hostnames (including "localhost") are not resolved and will be rejected.
Types ¶
type FetchOption ¶ added in v0.7.0
type FetchOption func(*fetchOptions)
FetchOption configures a fetch request.
func WithBody ¶ added in v0.7.0
func WithBody(body io.Reader) FetchOption
WithBody sets the request body.
func WithErrorHandler ¶ added in v0.7.0
func WithErrorHandler(handler func(*http.Response, []byte) error) FetchOption
WithErrorHandler sets a custom error handler for non-200 responses. The handler receives the response and body, and should return an error. If the handler returns nil, the default HTTPError will be returned. This is useful for parsing structured error responses (e.g., OAuth error responses).
func WithHeader ¶ added in v0.7.0
func WithHeader(key, value string) FetchOption
WithHeader adds a single header to the request.
func WithMaxResponseSize ¶ added in v0.28.1
func WithMaxResponseSize(size int64) FetchOption
WithMaxResponseSize sets a custom maximum response body size in bytes. The default is 1 MB. Use this to enforce tighter limits for endpoints that are expected to return small documents (e.g. OAuth metadata, CIMD documents).
func WithMethod ¶ added in v0.7.0
func WithMethod(method string) FetchOption
WithMethod sets the HTTP method for the request.
type FetchResult ¶ added in v0.7.0
type FetchResult[T any] struct { // Data is the parsed JSON response body. Data T // Headers are the response headers. Headers http.Header }
FetchResult contains the result of a successful JSON fetch operation.
func FetchJSON ¶ added in v0.7.0
func FetchJSON[T any]( ctx context.Context, client HTTPClient, requestURL string, opts ...FetchOption, ) (*FetchResult[T], error)
FetchJSON performs an HTTP request and parses the JSON response body. It sets the Accept header to application/json by default. For non-200 responses, it returns an HTTPError or the result of a custom error handler.
func FetchJSONWithForm ¶ added in v0.7.0
func FetchJSONWithForm[T any]( ctx context.Context, client HTTPClient, requestURL string, formData url.Values, opts ...FetchOption, ) (*FetchResult[T], error)
FetchJSONWithForm performs a POST request with form-urlencoded body and parses JSON response. This is a convenience wrapper around FetchJSON for token endpoints and similar APIs. It sets Content-Type to application/x-www-form-urlencoded and Accept to application/json.
type HTTPClient ¶ added in v0.7.0
HTTPClient is an interface for making HTTP requests. This interface is satisfied by *http.Client and allows for dependency injection in testing.
type HTTPError ¶ added in v0.7.0
type HTTPError struct {
// StatusCode is the HTTP status code.
StatusCode int
// Message is a description of the error (may be a preview of the response body).
Message string
// URL is the requested URL.
URL string
}
HTTPError represents an HTTP error response with status code, URL, and message.
type HttpClientBuilder ¶ added in v0.1.8
type HttpClientBuilder struct {
// contains filtered or unexported fields
}
HttpClientBuilder provides a fluent interface for building HTTP clients
func NewHttpClientBuilder ¶ added in v0.1.8
func NewHttpClientBuilder() *HttpClientBuilder
NewHttpClientBuilder returns a new HttpClientBuilder
func (*HttpClientBuilder) Build ¶ added in v0.1.8
func (b *HttpClientBuilder) Build() (*http.Client, error)
Build creates the configured HTTP client
func (*HttpClientBuilder) WithCABundle ¶ added in v0.1.8
func (b *HttpClientBuilder) WithCABundle(path string) *HttpClientBuilder
WithCABundle sets the CA certificate bundle path
func (*HttpClientBuilder) WithDisableKeepAlives ¶ added in v0.28.1
func (b *HttpClientBuilder) WithDisableKeepAlives(disable bool) *HttpClientBuilder
WithDisableKeepAlives disables HTTP keep-alive on the transport. When true, each request uses a fresh connection, ensuring the per-dial SSRF check fires on every request rather than being bypassed by a reused connection.
func (*HttpClientBuilder) WithInsecureAllowHTTP ¶ added in v0.4.2
func (b *HttpClientBuilder) WithInsecureAllowHTTP(allow bool) *HttpClientBuilder
WithInsecureAllowHTTP allows HTTP (non-HTTPS) URLs WARNING: This is insecure and should NEVER be used in production
func (*HttpClientBuilder) WithPrivateIPs ¶ added in v0.1.8
func (b *HttpClientBuilder) WithPrivateIPs(allow bool) *HttpClientBuilder
WithPrivateIPs allows connections to private IP addresses
func (*HttpClientBuilder) WithTimeout ¶ added in v0.8.3
func (b *HttpClientBuilder) WithTimeout(timeout time.Duration) *HttpClientBuilder
WithTimeout sets the HTTP client timeout
func (*HttpClientBuilder) WithTokenFromFile ¶ added in v0.1.8
func (b *HttpClientBuilder) WithTokenFromFile(path string) *HttpClientBuilder
WithTokenFromFile sets the auth token file path
type ValidatingTransport ¶ added in v0.0.37
type ValidatingTransport struct {
Transport http.RoundTripper
InsecureAllowHTTP bool
}
ValidatingTransport is for validating URLs prior to request