Published blocklist

What the relay refuses, in full.

A guard is only worth what it will not do. This page is the complete list of what Backfire will not dial, will not follow and will not accept — kept in step with the code that enforces it, so you can check the promise instead of believing it.

Try it

This is a real request against the live relay. It asks for the instance metadata service — the target behind most SSRF incidents — and gets refused before a socket opens.

the request
curl -s https://backfireapi.base44.app/functions/forward \
  -H "Authorization: Bearer backfire_…_api" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/latest/meta-data/","method":"GET"}'

What comes back

A 403 with a machine-readable code and the reason, written into your activity log. The attempt is recorded; your balance is not touched.

the refusal
{
  "ok": false,
  "request_id": "8f1c4b7a…",
  "error": {
    "code": "blocked_target",
    "message": "169.254.169.254 resolves to a private,
                loopback, link-local or metadata address."
  }
}

IPv4

Sixteen ranges are never dialled.

Checked against every address a hostname resolves to, not just the hostname string. A name that is both public and private resolves to a refusal.

ipv4 rangewhy it is refused
0.0.0.0/8This network — never a real destination
10.0.0.0/8Private range
100.64.0.0/10Carrier-grade NAT
127.0.0.0/8Loopback
169.254.0.0/16Link-local — where cloud metadata lives
172.16.0.0/12Private range
192.0.0.0/24IETF protocol assignments
192.0.2.0/24Documentation range
192.88.99.0/246to4 relay anycast
192.168.0.0/16Private range
198.18.0.0/15Benchmarking range
198.51.100.0/24Documentation range
203.0.113.0/24Documentation range
224.0.0.0/4Multicast
240.0.0.0/4Reserved
255.255.255.255/32Broadcast

IPv6

The same rules, written for the other stack.

ipv6 rulewhy it is refused
::Unspecified address
::1Loopback
fc00::/7Unique local
fe80::/10Link-local
fec0::/10Site-local
ff00::/8Multicast
2001:db8::/32Documentation range
2002::/166to4
64:ff9b::/96NAT64 — unwrapped and checked as IPv4
::ffff:0:0/96IPv4-mapped — checked as IPv4

Hostnames

  • localhost
  • metadata
  • metadata.google.internal
  • instance-data
  • metadata.azure.internal

Plus any name ending in .localhost, .local, .internal, .localdomain, .home.arpa.

Ports

  • 25SMTP
  • 465SMTPS
  • 587Submission

Mail ports are refused so the relay cannot be turned into a spam path.

Structural refusals

And the eight things a request cannot do.

Redirects are never followed

A 3xx comes back to you with its Location header and nothing else. The classic SSRF bypass — a public URL that answers 302 to 169.254.169.254 — never gets a second request from us.

Only http and https, with no credentials in the URL

file:, ftp:, gopher: and data: are refused. A URL carrying user:pass@ is refused too, because the relay is not a place to smuggle a credential past a log.

WebSocket targets need their own endpoint

A ws:// or wss:// target is refused at the forward endpoint and has to be opened through the socket route, where it gets its own ticket, expiry and frame counters.

8 MB in, 8 MB out

A request body above 8 MB is refused before the call. A response is read up to 8 MB and then stopped, so one oversized upstream cannot become a memory event on your bill or ours.

30 seconds, clamped

You may ask for any timeout up to 30 seconds; above that it is clamped, and below 1 second it is raised. The upstream cannot hold the relay open indefinitely.

Header hygiene, enforced

At most 32 headers, 1024 characters each, no CR or LF anywhere, hop-by-hop headers stripped. Authorization, cookie, key and token values are redacted in the log line we keep.

600 forwards a minute per key

Plus 1,200 a minute per account. Past the ceiling a request cools down for 10 seconds and is refused rather than queued — and a refusal is never charged.

DNS that fails, fails closed

No answer, a broken resolver, or an answer we cannot classify is a refusal. There is no fallback path that guesses what you meant.

What this does not do

It narrows the SSRF gap. It does not make it zero.

The relay checks the addresses a name resolves to, then makes the call — which resolves the name again. A hostname that answers publicly at check time and privately a moment later is a race this design narrows but does not eliminate. The write-up is public.

It also cannot tell you whether you were allowed to call a target in the first place, cannot pin a customer's allowlist to an address, and cannot reach a service that only accepts connections from inside your own network. Those are different products, and pretending otherwise is how security pages lose their readers.

Every refusal above has an error page with the exact retry semantics.

All error codes