Table of Contents

Class NetworkAddressPolicy

Namespace
NuvTools.Security.Network
Assembly
NuvTools.Security.dll

Decides whether an outbound connection may reach an address: the building block against server-side request forgery (SSRF) when an application fetches a URL somebody else supplied.

public sealed class NetworkAddressPolicy
Inheritance
NetworkAddressPolicy
Inherited Members

Remarks

The decision is taken on the IP address, never on the text of the URL. A host name proves nothing about where it resolves — a public domain can carry an A record of 10.0.0.5, and can change it between a check and the connection (DNS rebinding). Pair this policy with PublicNetworkConnector, which applies it to the address a socket actually connects to.

By default only publicly routable unicast addresses are allowed. Denied: loopback, private (RFC 1918 and IPv6 unique-local), link-local (which includes the cloud instance metadata endpoint 169.254.169.254), carrier-grade NAT, documentation and benchmarking ranges, multicast, reserved space, the IPv6 transition prefixes that embed an IPv4 address, and Azure's platform address 168.63.129.16, which is public in form and internal in fact.

Constructors

NetworkAddressPolicy(IEnumerable<IPNetwork>?, IEnumerable<IPNetwork>?, IEnumerable<string>?)

Creates a policy.

public NetworkAddressPolicy(IEnumerable<IPNetwork>? allowedNetworks = null, IEnumerable<IPNetwork>? additionalDeniedNetworks = null, IEnumerable<string>? additionalDeniedHostSuffixes = null)

Parameters

allowedNetworks IEnumerable<IPNetwork>

Networks allowed even though the defaults deny them — an internal backend a deployment trusts. Checked before the denied list, so keep it as narrow as the need.

additionalDeniedNetworks IEnumerable<IPNetwork>

Networks denied on top of the defaults.

additionalDeniedHostSuffixes IEnumerable<string>

Host name suffixes denied on top of the defaults.

Properties

PublicOnly

A policy allowing publicly routable addresses only.

public static NetworkAddressPolicy PublicOnly { get; }

Property Value

NetworkAddressPolicy

Methods

IsAllowed(IPAddress)

Whether a connection to this address is allowed.

public bool IsAllowed(IPAddress address)

Parameters

address IPAddress

Returns

bool

Remarks

An IPv4-mapped IPv6 address (::ffff:127.0.0.1) is judged as the IPv4 address it carries, which is where the socket ends up.

IsHostAllowed(string)

Whether a host name may be looked up at all. Names that can only mean "inside" — localhost and the internal suffixes — are refused without asking DNS.

public bool IsHostAllowed(string host)

Parameters

host string

Returns

bool

ResolveAllowedAsync(string, CancellationToken)

Resolves a host and returns its addresses, throwing when the name or any address it resolves to is not allowed.

public Task<IPAddress[]> ResolveAllowedAsync(string host, CancellationToken cancellationToken = default)

Parameters

host string
cancellationToken CancellationToken

Returns

Task<IPAddress[]>

Remarks

Any denied address refuses the whole name, not just that address. A name answering with one public and one private address is either misconfigured or an attempt to win a race, and neither is worth connecting to.

Exceptions

NetworkAddressNotAllowedException

The host or one of its addresses is denied.