netguard

package
v0.48.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package netguard is the one answer to "may filex dial this address?".

Two callers ask it, for the same reason: a URL an administrator or a plugin hands us must not become a probe of the server's own network. An install URL of http://169.254.169.254/… or http://10.0.0.5:9200/… is the SSRF shape, and so is a plugin's http_request to a public name that resolves to a private address. The check therefore runs on the DIALLED address, after DNS, and on every redirect hop — never on the string.

It lives in its own package so the storage-plugin downloader (internal/plugin) and the app-plugin outbound transport (internal/wasmplugin) cannot drift apart: one list of refused ranges, one guarded dialer, one error.

Index

Constants

This section is empty.

Variables

View Source
var ErrPrivateTarget = errors.New("resolves to a private or local address")

ErrPrivateTarget is what a guarded dial answers for a refused address. Callers match it with errors.Is to turn it into their own wording.

Functions

func DialContext

func DialContext(dialer *net.Dialer) func(ctx context.Context, network, addr string) (net.Conn, error)

DialContext is a net.Dialer's DialContext wrapped in the Refused check: the name is resolved here, every answer is checked, and the connection is made to the address that passed — so nothing can re-resolve to something else between the check and the dial.

func Private

func Private(ip net.IP) bool

Private says whether an address is inside the private network — loopback, link-local, RFC 1918 or ULA. This is the WEAKER question, asked about a destination filex will send credentials to: plain http:// is tolerable there and nowhere else. It deliberately does not include multicast or the unspecified address, which are not destinations at all.

func Refused

func Refused(ip net.IP) bool

Refused reports whether a resolved address is one an outbound request may never reach: loopback, link-local (v4 169.254/16 and v6 fe80::/10, which is where cloud metadata lives), the RFC 1918 / ULA private ranges, multicast and the unspecified address.

A nil IP counts as refused: "we could not tell" is not permission.

⚠⚠ Not only RFC 1918. net.IP.IsPrivate calls the shared address space 100.64.0.0/10 public, and that is where overlay meshes live (Cloudflare WARP 100.96/12, Tailscale, carrier-grade NAT). The other ranges below are not routable destinations either, and the IPv6 spellings that wrap an IPv4 address (NAT64, 6to4) are judged by the address they wrap.

func Transport

func Transport(responseHeaderTimeout time.Duration) *http.Transport

Transport returns an http.Transport that dials through the guard. Callers set their own timeouts on the fields they care about; proxies are off, because a proxy would do the resolving and the guard would never see it.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL