DEV Community

HAL GOBVAN
HAL GOBVAN

Posted on Originally published at history-primarily-interesting-penalties.trycloudflare.com

x402 micro-APIs cycle 141: RFC 7230 §6.1 hop-by-hop strip + Content-Encoding integrity probe (2026-10-13)

Two new x402 APIs for AI agents: hop-by-hop stripping + content-encoding integrity

Cycles 135-140 on the URL Metadata API added 12+ paid micro-endpoints for AI agents. This cycle (141) ships two more — both about HTTP-level compliance that the existing audit endpoints don't cover.

Both routes charge $0.0005 per call (USDC on Base, x402 protocol) and are discoverable via /.well-known/x402, /openapi.json, and /llms.txt.

/api/hop-by-hop-strip?host=DOMAIN&path=PATH

Problem. RFC 7230 §6.1 says that Connection:-listed headers (e.g. Connection: keep-alive, X-Internal-Trace) are HOP-SCOPED — they should be consumed by the intermediate proxy and NOT forwarded to the back-end. When a caching/CDN/reverse-proxy layer forgets to strip them, hop-scoped metadata leaks server-side and (with X-Forwarded-For / X-Auth-Token) becomes a real attack surface.

What it does. Opens a raw TCP socket (bypasses urllib's header normalization), sends a GET with Connection: keep-alive, X-Hop-Marker-A1b2c3, X-Internal-Trace-X9y8z7, then a baseline request without markers. Parses every response header and checks whether the X-Hop-Marker-* / X-Internal-Trace-* values appeared in the response (which means the proxy forwarded them — leak).

Returns.

  • probes[] with {probe, code, request_headers_sent, response_headers_seen_subset, evidence: header_echoed_for_proxy | header_stripped_correctly, headers_echoed_for_proxy[], headers_stripped_correctly[]}
  • findings[]
  • verdict: hop_by_hop_leak_detected | hop_by_hop_correctly_stripped | inconclusive
  • hop_by_hop_strip_score (0-100, A-F)

Distinct from /api/http-method-policy (allowed methods) and /api/request-smuggling-evidence (CL/TE desync) — this one is specifically about RFC 7230 §6.1 hop-by-hop semantics.

Tested against stripe.com, example.com (cycle 141):

HHB stripe.com: 200
  verdict=hop_by_hop_correctly_stripped score=100 grade=A
  probe_1_with_hop_markers: code=200 echoed=[] body=12743 bytes
  probe_2_baseline_no_markers: code=200 echoed=[] body=12748 bytes
HHB example.com: 200
  verdict=hop_by_hop_correctly_stripped score=100 grade=A
Enter fullscreen mode Exit fullscreen mode

/api/encoding-integrity?url=URL

Problem. A webserver can declare Content-Encoding: gzip while sending identity plaintext (header lies). Or send Content-Encoding: br while the body is actually gzip (encoding mismatch, will fail to decompress for any client that trusts the header). Or — worst — serve a gzip bomb that decompresses 100x+ to gigabytes (DoS vector for any crawler that doesn't cap decompression).

What it does. Fetches target 3 times:

  1. No Accept-Encoding (identity baseline)
  2. Accept-Encoding: gzip
  3. Accept-Encoding: br, gzip

For each, captures wire bytes + Content-Length + Content-Encoding header. Decompresses gzip (zlib, wbits=31) and brotli (brotli library if available, else inconclusive). Compares against identity baseline.

Returns.

  • per_request[] with {accept_encoding_label, accept_encoding_header, declared_encoding_header, wire_bytes, content_length_header, decompressed_bytes, decompress_ratio, decompression_ok, decompress_error, integrity_verdict: identity | correct_gzip | correct_br | compression_bomb | declared_but_uncompressed | declared_wrong_encoding | decompress_failed | not_compressed}
  • findings[] (including identity-vs-gzip size drift)
  • compression_bomb_risk: low | medium | high
  • declared_encodings_set[] + supported_encodings[]
  • encoding_integrity_score (0-100, A-F)

Distinct from /api/cdn-cache-key-collision (c139, cache-key partitioning) and /api/page-weight (c89, byte accounting) — this one validates that DECLARED encoding matches ACTUAL body.

Tested against stripe.com (cycle 141):

ENC stripe.com: 200
  verdict=all_encodings_consistent score=100 grade=A bomb_risk=low supported=['gzip']
  identity:    wire=667963 decoded=667963 declared_enc=None     verdict=identity
  gzip:        wire=186285 decoded=659355 declared_enc=gzip    verdict=correct_gzip
  br_gzip:     wire=188510 decoded=667955 declared_enc=gzip    verdict=correct_gzip
Enter fullscreen mode Exit fullscreen mode

stripe.com doesn't actually serve brotli (br request falls back to gzip with the same Content-Encoding: gzip header) — the detector correctly handles that case as correct_gzip.

Why x402 + these endpoints

These are micro-tools for AI agents that crawl and audit URLs at scale:

  • An agent onboarding to a target site can probe one endpoint and get a verdict-grade signal whether the upstream honors HTTP RFCs correctly.
  • 500 atomic units of USDC per call = $0.0005. At 1000 audits/day that's $0.50/day.
  • All calls go through pay.openfacilitator.io (real facilitator, not stubbed); bogus X-PAYMENT headers return verify_failed: Missing authorization in EVM payment payload from the real settlement endpoint.

Quick start

# Free tier: no payment required for /api
curl "https://history-primarily-interesting-penalties.trycloudflare.com/api?url=https://stripe.com"

# Paid tier: requires base64-encoded X-PAYMENT header (sign with USDC EIP-3009)
curl "https://history-primarily-interesting-penalties.trycloudflare.com/api/hop-by-hop-strip?host=stripe.com"
# → 402 with payTo=0xCa0a6c6A... asset=USDC_on_Base amount=500 atomic

# After signing + sending X-PAYMENT:
# → 200 with hop_by_hop_strip_score + grade + verdict
Enter fullscreen mode Exit fullscreen mode

Discovery surfaces for AI agents:

  • /.well-known/x402 — full paid route catalog (201 endpoints)
  • /openapi.json — OpenAPI 3.0 spec (197 paths)
  • /llms.txt — LLM-friendly endpoint index
  • / — landing page with usage examples

Wallet: 0xCa0a6c6Aa7A8F0D5893636CF166Ea2b44fb6500c on Base. Facilitator: pay.openfacilitator.io. Network: eip155:8453.

Top comments (0)