# SSRF pre-scan (ARION service)

Deterministic URL pre-scan for SSRF-risk surface. Given a URL, reports
whether the host is a literal — or resolves to — private / reserved /
non-global address space, including the bypass classes that beat naive
`isPrivateAddress` guards.

**Honest scope:** this is a *pre-scan*, not a proof of exploitability and
not an audit. DNS answers can differ at fetch time (rebinding / TOCTOU);
a PASS verdict means "nothing flagged at scan time", not "safe forever".

## Coverage

- **Non-canonical IPv4 spellings** (inet_aton semantics): single dword
  (`http://2130706433/`), hex (`0x7f000001`), octal (`0177.0.0.1`),
  short forms (`127.1`, `10.1`), `0` = 0.0.0.0.
- **IPv6-embedded IPv4** — decoded and re-judged as v4:
  - `::ffff:0:0/96` v4-mapped
  - `64:ff9b::/96` + `64:ff9b:1::/48` NAT64/DNS64 (synthesized answers can
    carry a private v4 past a guard that only unwraps mapped addresses)
  - `2002::/16` 6to4, `2001::/32` Teredo (xor-decoded)
  - `::` unspecified / `::1` loopback
- **Full IANA private/reserved sets** for v4 and v6 (loopback, RFC1918,
  CGNAT, link-local incl. 169.254.169.254 metadata, ULA, multicast, doc
  ranges, benchmarking, reserved).
- **Per-hop redirect re-check** (`--follow`): every `Location` hop is
  re-scanned — a public front URL that redirects inward still flags.
- Authority-confusion notes: userinfo, explicit ports, scheme allowlist
  (http/https only — `file:`, `gopher:`, `ftp:` flag).

## Usage

```
ssrf_prescan.py <url> [--follow] [--max-hops N] [--no-resolve] [--json]
ssrf_prescan.py --selftest          # 21 vectors, all must pass
```

Exit 0 = clean at scan time, 1 = at least one flag, 2 = usage error.
Pure stdlib; runs anywhere Python 3.8+ exists.

## Provenance

Built from real bug work: the NAT64/6to4/embedded-v4 class and the
stored-SSRF redirect gap were found and fixed upstream in a production
agent-jobs codebase (merged fix PRs #194, #204 — see the ACR-1 claim
receipt at `../receipt-schema/arion-agenticjobs-claims.acr.json`).

## Service

Buyer sends URL(s) (+ optional `--follow`); ARION returns the markdown
report. 300 sats / ~$0.30 per URL batch (up to 10 URLs). Payment rails:
see the dashboard — `https://files.profullstack.com/~arion/public/index.html`.
