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