api/utils/ssrf-protection

SSRF (Server-Side Request Forgery) protection utilities shared by the core API (validateRedirect for app.redirect_url) and the Hooks plugin's HTTPEffect.

Provides IP blocklist checking, DNS-level validation, and URL safety verification to prevent requests to internal/private network addresses, cloud metadata endpoints, and other dangerous targets.

Uses ipaddr.js for robust IP address parsing and range classification, covering all RFC-defined private, reserved, loopback, link-local, multicast, carrier-grade NAT, and documentation ranges for both IPv4 and IPv6 (including IPv4-mapped IPv6 and NAT64).

  • URL parse time validation with DNS (isUrlSafe)
  • Protocol restriction (only http/https)
  • Redirects disabled (followRedirect: false via getSsrfSafeOptions)
  • Revalidation after template expansion (when doing request in http effect)
Description:
  • SSRF (Server-Side Request Forgery) protection utilities shared by the core API (validateRedirect for app.redirect_url) and the Hooks plugin's HTTPEffect.

    Provides IP blocklist checking, DNS-level validation, and URL safety verification to prevent requests to internal/private network addresses, cloud metadata endpoints, and other dangerous targets.

    Uses ipaddr.js for robust IP address parsing and range classification, covering all RFC-defined private, reserved, loopback, link-local, multicast, carrier-grade NAT, and documentation ranges for both IPv4 and IPv6 (including IPv4-mapped IPv6 and NAT64).

    • URL parse time validation with DNS (isUrlSafe)
    • Protocol restriction (only http/https)
    • Redirects disabled (followRedirect: false via getSsrfSafeOptions)
    • Revalidation after template expansion (when doing request in http effect)
Source:

Members

(inner, constant) ALLOWED_PROTOCOLS

Description:
  • Allowed URL protocols for outbound requests.

Source:

Allowed URL protocols for outbound requests.

(inner, constant) BLOCKED_HOSTNAMES

Description:
  • Hostnames known to serve cloud metadata / internal services. Checked as exact match (case-insensitive).

Source:

Hostnames known to serve cloud metadata / internal services. Checked as exact match (case-insensitive).

Methods

(inner) getSsrfSafeOptions(requestOptions) → {object}

Description:
  • Build got-compatible request options with SSRF protection baked in.

    Disables redirects to prevent redirect-based SSRF bypasses.

Source:
Parameters:
Name Type Description
requestOptions object

base request options (uri, timeout, headers, etc.)

Returns:

the same options object with SSRF settings injected

Type
object

(inner) isBlockedHostname(hostname) → {boolean}

Description:
  • Check whether a hostname is a known dangerous internal service.

Source:
Parameters:
Name Type Description
hostname string

The hostname to check (will be lowercased)

Returns:

true if the hostname should be blocked

Type
boolean

(inner) isBlockedIP(ip) → {boolean}

Description:
  • Check whether an IP address (v4 or v6) is private/reserved/internal.

    Uses ipaddr.js range() classification. Only 'unicast' addresses are considered safe. All other ranges are blocked:

    • unspecified (0.0.0.0/8, ::)
    • loopback (127.0.0.0/8, ::1)
    • private (10/8, 172.16/12, 192.168/16)
    • linkLocal (169.254/16, fe80::/10)
    • multicast (224/4, ff00::/8)
    • broadcast (255.255.255.255)
    • reserved (192.0.0/24, 192.0.2/24, 192.88.99/24, 198.18/15, 198.51.100/24, 203.0.113/24, 240/4, 2001:db8::/32)
    • carrierGradeNat (100.64/10)
    • uniqueLocal (fc00::/7)
    • ipv4Mapped (::ffff:0:0/96 — unwrapped and re-checked as IPv4)
    • rfc6052 (64:ff9b::/96 NAT64)
    • discard (100::/64)
Source:
Parameters:
Name Type Description
ip string

IP address string

Returns:

true if the IP should be blocked

Type
boolean

(async, inner) isUrlSafe(urlString)

Description:
  • Validate a URL string for SSRF safety.

Source:
Parameters:
Name Type Description
urlString string

The URL to validate

(inner) stripIPv6Brackets(hostname) → {string}

Description:
  • Strip IPv6 brackets from a hostname if present. new URL('http://[::1]/').hostname returns '[::1]' with brackets, but net.isIP() and our IP checkers expect '::1' without brackets.

Source:
Parameters:
Name Type Description
hostname string

hostname possibly wrapped in brackets

Returns:

hostname with brackets stripped if it was a bracketed IPv6

Type
string