Standard Library

url_policy

import url_policy decides whether a URL is safe to fetch from a public API or webhook. It is the runtime side of the UrlPolicy validator declared inside an api block and is used by the PublicUrl and PublicWebhookUrl validators.

SSRF threat model

A public API that fetches user-supplied URLs is exposed to server-side request forgery: a malicious client points the server at an internal address, a cloud metadata endpoint, or a Via control-plane port. This module rejects the unsafe categories before any HTTP request is issued.

CategoryBlocked because
Non-HTTPS schemesOnly https is allowed; http, file, gopher are rejected.
Loopbacklocalhost, *.localhost, IPv4 loopback 127/8, IPv6 ::1.
Private and link-local IPv410/8, 172.16/12, 192.168/16, 169.254/16, 0.0.0.0/8.
IPv6 unique-local and link-localfc00::/7, fe80::/10.
Cloud and platform metadataCommon metadata and cluster suffixes (see list below).
Bad hostnamesEmpty host, .., embedded backslash or newline.

Metadata and cluster suffixes blocked under "Cloud and platform metadata": metadata.google.internal, host.docker.internal, kubernetes.default.svc, .svc, .cluster.local, .local, .internal.

public_outbound_url_allowed(url, [resolved_addresses], allow_via_internal) returns True only when the scheme, hostname, and (optionally) every resolved address pass.

public_webhook_url_allowed(url) is the strict webhook entry point: it never allows internal services and never accepts resolved addresses.

Redirect chains

import url_policy

let chain = ["https://example.com/initial", "https://example.com/step-2"]
if not url_policy.public_outbound_redirect_chain_allowed(target, chain) {
    return Err(api_boundary_error("validation_error", "url", "redirect chain not allowed"))
}

public_outbound_redirect_chain_allowed(url, chain, allow_via_internal) re-runs the per-URL check for the original target and every redirect target. A single internal-host redirect aborts the chain.

Webhook example

import url_policy
import api_response

def register_webhook(request: RegisterWebhookRequest, ctx: RequestContext) -> Str {
    if not url_policy.public_webhook_url_allowed(request.url) {
        return api_response.validation_error("url", "must be a public https URL", ctx.request_id.value)
    }
    store.create_webhook(request.url, request.events)
    return api_response.ok_object("webhook", Json.empty_object())
}

For DSL-declared validators, prefer the UrlPolicy { ... } block inside the api declaration; it forwards to these functions and is the source of truth for OpenAPI metadata and release artifacts.

When to allow internal services

allow_via_internal = True is reserved for inter-service calls inside the Via platform itself, where the destination is a trusted control-plane endpoint. Application code should never set this flag.

← xml
config →