Skip to main content

A two-layer SSRF egress guard for Python's stdlib HTTP client that survives DNS rebinding.

Project description

pantheon-ssrf-guard

tests PyPI Python License

A small, dependency-free SSRF egress guard for Python's standard-library HTTP client — one that survives DNS rebinding.

The guarantee: an outbound request cannot reach a private, loopback, link-local, cloud-metadata, or CGN address — even if the hostname resolves public at check time and rebinds to an internal IP before the socket connects.

Extracted from PANTHEON, a multi-tenant AI substrate, where it is the single canonical guard on every outbound path (link imports, uploaded-URL fetches, external MCP-server transports).

Why a pre-check isn't enough

The common "block internal hosts" approach resolves the hostname and rejects private IPs before connecting. An attacker defeats it with DNS rebinding: the name resolves to a public IP when you check it, then to 127.0.0.1 / 169.254.169.254 (cloud metadata) / an internal service by the time the socket actually opens.

pantheon-ssrf-guard uses two layers:

  1. host_is_public(host) — the fast pre-check: reject if any resolved address is non-public.
  2. GuardedHTTP(S)Connection — at connect time, re-check the IP the socket actually reached. This is the layer a pre-check can't provide, and it's what closes the rebind window.

The classifier's catch-all is not ip.is_global, so it also rejects everything the obvious flags miss — RFC 6598 shared/CGN space (100.64.0.0/10, used by Kubernetes/internal load balancers and the Alibaba/Tencent/Oracle metadata endpoint 100.100.100.200), plus benchmark, documentation, and NAT64 ranges.

Install

pip install pantheon-ssrf-guard   # or: copy the single ssrf_guard.py file into your project

Use

from ssrf_guard import guarded_opener, SsrfBlocked

opener = guarded_opener()          # https-capable; redirects refused by default (each hop re-checked if allowed)

try:
    with opener.open("https://example.com/data.json", timeout=10) as resp:
        body = resp.read()
except SsrfBlocked:
    ...   # the target resolved (or rebound) to a non-public address — refused before any data was sent

Lower-level pieces are exported too if you're building your own client:

from ssrf_guard import host_is_public, ip_is_public, peer_is_public
from ssrf_guard import GuardedHTTPHandler, GuardedHTTPSHandler

What it does not do

  • It doesn't proxy, cache, or rate-limit — it only refuses non-public destinations.
  • It guards urllib/http.client. For httpx/requests you'd apply the same idea at their transport layer (the classification functions here are reusable).
  • It is not a WAF; it's the one specific control that stops server-side request forgery to internal infrastructure.

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pantheon_ssrf_guard-0.1.0.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pantheon_ssrf_guard-0.1.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file pantheon_ssrf_guard-0.1.0.tar.gz.

File metadata

  • Download URL: pantheon_ssrf_guard-0.1.0.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pantheon_ssrf_guard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 98386bb4812f0610cb34fd8490a515e545466eb24ddc4d0e1104927c1aac295f
MD5 ed65a1e9314800df2b54aa8c9a3a5d9e
BLAKE2b-256 f950b74fb7019a0276719fb5eaea00a9fedf2cd2c4fb0739a1e5034bdeac2210

See more details on using hashes here.

Provenance

The following attestation bundles were made for pantheon_ssrf_guard-0.1.0.tar.gz:

Publisher: publish.yml on Igfray/pantheon-ssrf-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pantheon_ssrf_guard-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pantheon_ssrf_guard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 247dad26cc0dcc8c4817dc3017eeedc21b461e2c45b57188f7eb8e9243815442
MD5 9361209f07e641487067ad706292dd7e
BLAKE2b-256 fd16dfc65518ad489a01c6634ea0c2a4fc0145cbae175856cd4bd64353dc9da7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pantheon_ssrf_guard-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Igfray/pantheon-ssrf-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page