Table of Contents

Class UriSafetyValidator

Namespace
NetPdf
Assembly
NetPdf.dll

Per Phase B B-7 — the SSRF / SSRP gate every resource-loader implementation is expected to call before issuing an outbound fetch. Combines two checks:

  1. Scheme allowlist — only schemes enabled on the active SecurityPolicy are accepted. Default policy (SafeDefault) accepts file: only when the path is under BaseUri + data: inline content; both http: and https: are off.
  2. Private / loopback / link-local IP blocklist for HTTP(S) hosts. Catches the standard SSRF amplifier set: cloud-metadata endpoints (169.254.169.254 AWS / GCE / Azure / Alibaba; fd00::/8 IPv6 ULA), localhost (127.0.0.0/8, ::1), private LAN (10/8, 172.16/12, 192.168/16, fc00::/7), link-local (169.254/16, fe80::/10), multicast (224.0.0.0/4, ff00::/8), and unspecified (0.0.0.0, ::). Hosts that resolve via DNS are NOT validated here — the loader must resolve to IP, then re-validate to defend against DNS rebinding. IsBlockedIp(IPAddress, out string) exposes the IP check standalone for that use.

Phase B contract. NetPdf v1 ships with no default loader, so this validator's only client today is unit tests. Phase 5 wires a real IResourceLoader implementation that calls ValidateScheme(Uri, SecurityPolicy) at intent time + IsBlockedIp(IPAddress, out string) after DNS resolution, refusing the fetch on any "unsafe" verdict and emitting RES-LOAD-FAILED-001 with the rejection reason.

What this does NOT do. Network policy (firewalls, egress proxies, captive portals) belongs at the OS / fabric layer; this validator addresses application-level SSRF defense only. It also does not handle HTTP redirects — the loader must re-validate the redirect target host after each hop.

public static class UriSafetyValidator
Inheritance
UriSafetyValidator
Inherited Members

Methods

IsBlockedIp(IPAddress, out string)

True when ip falls in any of the well-known SSRF amplifier ranges (loopback, private, link-local, cloud-metadata, multicast, unspecified). The reason out parameter names the matching range so the caller can produce a specific diagnostic.

public static bool IsBlockedIp(IPAddress ip, out string reason)

Parameters

ip IPAddress
reason string

Returns

bool

Validate(Uri, SecurityPolicy)

Validate uri's scheme + host against policy. For host validation, the URI host is parsed as an IP literal where applicable; symbolic hostnames pass the host check (the loader is expected to call IsBlockedIp(IPAddress, out string) after DNS resolution to defend against DNS rebinding).

public static UriSafetyValidator.Verdict Validate(Uri uri, SecurityPolicy policy)

Parameters

uri Uri
policy SecurityPolicy

Returns

UriSafetyValidator.Verdict

ValidateRedirect(Uri, Uri, SecurityPolicy, int)

Per Phase C C-6 — validate an HTTP redirect target. The loader calls this for every Location: header before issuing the next-hop fetch. Three checks layered on top of Validate(Uri, SecurityPolicy):

<ol><li>The redirect target itself passes scheme + host
  policy (delegates to <xref href="NetPdf.UriSafetyValidator.Validate(System.Uri%2cNetPdf.SecurityPolicy)" data-throw-if-not-resolved="false"></xref>) — re-checks the IP
  blocklist on the new host so an open-redirect → SSRF chain
  (initial URL safe, redirect target on <code>169.254.169.254</code>) is
  blocked at the moment of redirection.</li><li>The hop count is below
  <xref href="NetPdf.SecurityPolicy.MaxRedirectHops" data-throw-if-not-resolved="false"></xref>. Each call records
  one hop; once exhausted, return <xref href="NetPdf.UriSafetyValidator.SafetyOutcome.Unsafe" data-throw-if-not-resolved="false"></xref>
  with a redirect-chain reason.</li><li>Cross-scheme downgrade rejection: <code>https</code>
  → <code>http</code> redirects are blocked (typical browser behavior +
  defense against MITM-induced downgrade). Same-scheme +
  <code>http</code> → <code>https</code> upgrades pass.</li></ol>
public static UriSafetyValidator.Verdict ValidateRedirect(Uri origin, Uri redirectTarget, SecurityPolicy policy, int hopsAlreadyFollowed)

Parameters

origin Uri
redirectTarget Uri
policy SecurityPolicy
hopsAlreadyFollowed int

Returns

UriSafetyValidator.Verdict

ValidateScheme(Uri, SecurityPolicy)

Scheme-only check (no host inspection). Useful when the caller has not yet resolved the URL or wants to short-circuit on scheme rejection before paying DNS cost.

public static UriSafetyValidator.Verdict ValidateScheme(Uri uri, SecurityPolicy policy)

Parameters

uri Uri
policy SecurityPolicy

Returns

UriSafetyValidator.Verdict