RC RANDOM CHAOS

Cloudflare shipped an authorization boundary in 2025

How x402 charge gateways behind Cloudflare turn old CDN misconfigurations - origin IP exposure, cache deception, verify-settle races - into priced exploitation.

· 7 min read
Cloudflare shipped an authorization boundary in 2025

Coinbase revived HTTP 402 in 2025. Cloudflare shipped a facilitator for it the same year. The status code sat reserved in the HTTP spec for two decades - Payment Required, defined, unused. x402 gives it a wire protocol. A client requests a resource. The server answers 402 with a JSON body naming the amount, the asset, the network, and a payTo address. The client signs a payment authorization - an EIP-3009 transferWithAuthorization for USDC is the common form - and retries with an X-PAYMENT header. A facilitator verifies the signature, settles the transfer, and only then is the resource released. Cloudflare frames this as pay-per-crawl: per-request charging for agentic and automated access. The charge gateway now sits inline on the request path. It is an authorization boundary. It was not built to be one.

There is no CVE for this. That is the finding. This is not a heap bug with a patch delta and an affected version range. It is a trust-boundary class - CWE-441 unintended intermediary, CWE-639 authorization bypass through a user-controlled key, CWE-347 improper signature verification, CWE-524 cache exposure - routed through a new inline component. No advisory is coming, because the gateway works as designed. The failure lives in what the deployment assumes about it.

Characterized as a class, the vector reads AV:N/AC:L/PR:N/UI:N/S:C - network reachable, low attack complexity, no privileges, no user interaction, scope changed because a failure in the edge component reaches the origin’s protected resources. That lands in the critical band. No advisory carries that string, because the gateway is not defective. The deployment is. This is the analysis the advisory omits, because the vendor has nothing to disclose.

Start with the handshake. The 402 flow separates verification from settlement. The facilitator verifies that a payment authorization is well-formed and signed. It settles by submitting the transfer to the network. Between those two events the resource decision is made. If the gateway serves on verify rather than on confirmed settlement, delivery and payment are no longer atomic. A signed authorization that is valid at verify time but never lands - insufficient balance, a reverted transaction, a reorg, a reused nonce - produces a delivered resource with no completed payment. The gap is milliseconds to blocks wide. It is deterministic, not theoretical. EIP-3009 authorizations carry a nonce. Verification that does not durably burn that nonce before delivery admits replay of the same signed payload.

Now the origin. Cloudflare is a reverse proxy. The origin sits behind it. The near-universal deployment trusts the edge: the origin accepts connections from Cloudflare IP ranges and treats a forwarded request as legitimate. The charge decision happens at the edge. The origin has no knowledge of it. The origin serves whatever the edge forwards. This is the load-bearing assumption, and it fails in two directions.

Direction one. The resource is reachable without the edge. Origin IP exposure is a decade-old, routine finding. The origin address leaks through historical DNS records, certificate transparency logs listing the origin in a SAN, a subdomain that resolves direct, an email header, or mass-scan correlation. A request sent straight to the origin never touches the facilitator. No 402. No X-PAYMENT header. No settlement. No edge log. The resource is served for free by an origin that assumed the edge would gate it. The charge gateway is not bypassed - it is never in the path.

Direction two. The gateway is pointed at a resource it does not own. Nothing in the 402 handshake binds the payTo party to ownership of the resource being sold. A facilitator placed in front of a proxied origin will charge for bytes it has no rights to. Any resource reachable through the CDN can be fronted by a charge gate that collects payment for someone else’s content. The protocol monetizes access. It does not prove authority over what is accessed. That is the literal reading of charging for any resource behind the CDN, and it is a property of the design, not a bug in an implementation.

Between those two failures sits path and host confusion. The facilitator makes its charge and access decision on a normalized view of the request - a path, a host, a route. The origin resolves the raw request under its own normalization. When those two normalizations disagree, the resource priced and the resource served diverge. A request the gateway reads as a cheap or free path can resolve at origin to a different, gated object. Path parameter tricks, trailing-segment confusion, and host header handling are the same primitives that have broken CDN routing for years. The charge layer inherits every one of them because it is one more component that must agree with the origin on what a URL means.

Then caching. Web cache deception has been public since Omer Gil demonstrated it at Black Hat in 2017. A paid, personalized 200 response gets written into the edge cache under a key that a later, unpaid request can hit. If the cache key omits the payment or identity dimension, gated content is served from cache to a requester who never paid. The inverse - a crafted request that causes a sensitive origin response to be cached publicly - is the same defect from the other side. x402 raises the stakes because the cached object now has a price, and cache HIT means that price was collected zero times for delivery number two onward.

Map it to technique. Initial access to the free-retrieval path is T1190, exploitation of a public-facing application - the public face here is the origin the edge failed to hide. The facilitator abused as an intermediary that fetches and serves arbitrary origin resources is T1090, use of a proxy to reach an asset. None of this requires memory corruption, a sandbox escape, or a dropped implant. It requires disagreement between two components about identity, ownership, and state. That is why it is predictable. The exploitation classes were documented before the gateway existed. The gateway is a new delivery mechanism for them.

Telemetry decides whether any of this is seen. On the Cloudflare side, Logpush carries the fields that matter: EdgeResponseStatus shows the 402 and the subsequent 200, CacheCacheStatus shows HIT versus MISS versus DYNAMIC, ClientRequestHost and ClientRequestURI show what was asked for, EdgePathingOp and EdgePathingSrc show how the edge routed it. A 402 that never transitions to a settled 200, or a 200 with CacheCacheStatus HIT on a path that carries priced content, is the signal. Most deployments do not correlate the edge delivery log against the settlement ledger, so a delivered resource with no matching on-chain settlement is invisible. That reconciliation join - delivery events against confirmed settlements - is the single highest-value detection, and it is almost never built.

On the origin side, the blind spot is structural. The origin sees a request from a Cloudflare IP and a 200 it served. It does not see payment, because payment never reached it. The direct-to-origin bypass produces the one log line that exposes the whole failure: a 200 to a source IP outside Cloudflare’s published ranges. An origin that ingested Cloudflare’s IP list and alerted on any inbound connection from outside it would catch the dominant bypass. Most origins do not log the source IP against that list, do not alert, and do not enforce it. The request looks normal because the origin was configured to treat the edge as the only possible caller and then never verified the claim.

The verify-settle race leaves its own trace, if anyone joins the two ledgers. Facilitator delivery events carry a timestamp and a resource identifier. On-chain settlement carries a transaction hash, a nonce, and a confirmation height. Unmatched deliveries - served resources with no confirmed, non-reverted settlement - are free retrievals. Nonces appearing twice against the same authorization are replays. Neither fires an alert by default, because the delivery system and the settlement system are usually different systems owned by different teams.

There is nothing to patch. That is the residual reality. The fixes are configuration and enforcement, independent of the gateway vendor. Authenticated Origin Pulls binds the origin to accept only mTLS connections presenting Cloudflare’s client certificate, which closes the direct-to-origin path that predates x402 by ten years. Origin-side authorization that does not delegate the entire access decision to the edge removes the single point of trust. Cache keys that include the payment or identity dimension, or gated content marked uncacheable, close the deception path. Settlement confirmed before delivery - settle-then-serve, not verify-then-serve - closes the race and the replay. Binding payTo to proven ownership at gateway registration closes the monetize-what-you-do-not-own case.

The charge gateway did not create the origin exposure. It did not invent web cache deception or host confusion. It monetized resources that were already reachable through misconfigurations documented for a decade, and in doing so gave every one of those failures a price tag and a reason to be exploited at scale. HTTP 402 answers a question about payment. It answers nothing about who is allowed to reach the byte behind it. Treating a charge gateway as access control is the misconfiguration. Every resource behind the CDN inherits it.

Share

Keep Reading

Stay in the loop

New writing delivered when it's ready. No schedule, no spam.