Scope and evidence
- Source review
- Cloud scope
- Cloudflare
- Availability
- Varies by feature
- Exercise status
- Exercises not run
Conditions and limits
- Worker request semantics, Access validation, and the historical Containers incident cover different products; provider remediation does not verify an application's own controls.
Start with the authority an attacker could gain
Consider a synthetic document assistant. It stores private records, calls one external provider, and lets an AI draft a response. An anonymous caller, a legitimate user requesting someone else's record, a hostile provider response, and a manipulated document are four different starting points. A package audit cannot establish that all four are contained.
For each route, write down the input an attacker can control and the effect they want: read a record, change data, send a secret, execute a tool, or consume paid capacity. Follow the implementation between them. The outcome should be a small reproducible test, not a collection of reassuring settings. All exercises below use local mocks and synthetic data; no production service was attacked for this article.
Separate identity from permission to act on a record
Authentication answers who made the request. Authorization answers whether that principal may perform this operation on this resource. Check both before a read, write, or outbound request that uses privileged data.
For example, user A successfully logging in does not authorize recordId=B-record. Resolve the principal from the validated session, obtain the record in that principal's authorized scope, then execute the operation. A hidden button, an unguessable identifier, or a client-provided owner field cannot replace that decision. This follows OWASP's authorization guidance: deny by default and validate permission on every request.
When using Access in front of a Worker, verify the Access JWT at the origin as well. Check the signature with the expected key source and validate the expected issuer, application audience, and time claims. A supplied email header is not a validated identity. Check alternate routes and direct origins too. Cloudflare's JWT validation documentation describes the origin verification contract.
Cookie-authenticated state changes also need the application's CSRF defense. CORS alone does not prevent another client from sending a request or establish its owner. Keep these checks on the server path that actually performs the side effect.
An approved URL can redirect authority elsewhere
SSRF occurs when an attacker makes the server issue an unintended request using the server's network position or credentials. If the product only needs one known provider, accept a provider-specific identifier and construct the destination server-side. Avoid adding an arbitrary URL input merely for flexibility. Applications that must fetch arbitrary sites need a broader egress design, including DNS and private-network restrictions. OWASP distinguishes these two cases.
Cloudflare Workers has a particularly relevant redirect contract: a newly created Request defaults to follow, and followed redirects forward headers including Authorization and Cookie across hosts. An incoming client Request defaults to manual. Workers does not implement redirect: "error"; it throws during Request construction. Use manual and reject redirects, or explicitly validate every permitted hop and reconstruct headers. These are documented Worker Request semantics, not browser assumptions.
For an authenticated provider call that does not need redirects, the intended sequence is:
Validate session and record ownership
Construct HTTPS URL from a server-owned provider origin and validated ID
Create only the provider headers the call needs
Fetch with manual redirect handling and an overall deadline
Reject 3xx without making a second request; cancel/discard its body
Read at most the configured number of response bytes
Validate the expected response structure
Return an application result without upstream secrets or raw errorsThis is a design sequence, not a complete implementation. In a local test, return a redirect to a second mock origin. Assert that the second origin receives zero requests and the response does not include the provider token. Testing only the final HTTP status would miss a secret that was transmitted before the handler returned an error.
Bound the work before and during parsing
Set limits according to the operation: request bytes, field count, string length, nesting depth where supported, response bytes, concurrent requests, and elapsed time. A byte limit does not automatically constrain every expensive parser behavior. Types in source code do not validate network input.
For streaming responses, count received bytes. A Content-Length header can be absent or inaccurate. Stop reading and cancel the upstream operation at the limit or deadline. Cancel/discard rejected redirect and HTTP error bodies too, so failure paths do not leave response streams running. Do not return the upstream body verbatim on failure; return a stable application error and a request ID. OWASP REST guidance covers input limits, media types, and avoiding internal error disclosure.
Set numeric limits from a concrete service requirement, then test the boundary and one value beyond it. For example, if a small metadata endpoint is designed for a 64 KiB response and a five-second total deadline, test a valid small response, a stream exceeding 64 KiB, and a stream that never finishes. These are illustrative design values, not universal defaults or measured production limits.
Keep private data out of shared reuse
Inspect caches and memoized computation as data flows too. An authenticated response must not become an anonymous response because a cache key omitted the user or tenant. If shared reuse is unnecessary, avoid it on private records. If it is necessary, make the authorized scope part of the design and test it with two principals.
Warm the relevant path with A's synthetic record. Then request the same route as B and anonymously, including error and redirect paths. Assert that neither response contains A's unique marker. A cache miss on the first request proves little about a warm process or repeated request.
Platform isolation and application authorization remain different responsibilities. In its September 24, 2026 Containers report, Cloudflare described residual storage exposure and a fleet-side remediation, with no customer configuration change required and no evidence of malicious exploitation in the available telemetry. That historical report does not mean an application has the same defect, nor does the provider's fix validate the application's ownership checks.
Treat model output as a proposed action
An external document may tell an agent to send data to a new destination or claim an administrator approved a tool. That text is content, not authority. Validate the selected tool, arguments, destination, resource owner, and current user permission outside the model before executing it.
OpenAI's March 11, 2026 analysis connects untrusted input to dangerous capabilities through source–sink analysis. For a custom application, a useful test assumes the model was persuaded: can the execution layer still refuse the unauthorized action? A stronger prompt or input classifier alone cannot establish that boundary.
Include economic effects in the design. Cap tool calls, retries, input/output sizes, concurrency, and total elapsed work in the execution layer. Identify the usage pool each request consumes. A disconnected browser should not leave unbounded generation running. If an upstream timeout leaves a write's outcome unknown, reconcile it before retrying; an error message does not prove the write never happened.
Build a compact attacker-oriented regression set
Use distinct synthetic users and mock destinations. Assert the observable side effect as well as the response.
| Test condition | Required observation |
|---|---|
| A requests A's permitted record | Expected result, one authorized read |
| B requests A's record | Denied; no private result or privileged outbound call |
| Anonymous request to an alternate origin or route | Denied before private work |
| Provider redirects to another mock origin | No request or credential reaches that origin |
| Response stream exceeds its limit or deadline | Reading stops and operation is cancelled |
| A warms a cache, then B requests the route | A's marker never appears for B |
| Model proposes an unauthorized destination or tool | Execution layer refuses; zero side effects |
| Client repeats a side-effect request after timeout | At most one authorized effect, with an explicit final state |
For AI-assisted code review, use this instruction:
Trace attacker-controlled input to private reads, writes, external requests, tool execution, and paid work. Identify each enforcing server boundary and a concrete way to test its absence. Use local mocks and synthetic principals. Repair confirmed failures, preserve legitimate behavior, and report code checks, deployment checks, and untested assumptions separately.
A passing local test proves only the path and runtime it exercised. After release, verify the changed route and authorization boundary through the normal deployment process. Keep logs useful with request IDs, decisions, limits, and stop reasons while excluding credentials and raw private content.
MENTAL MODEL / REASONING ORDER
From an announcement to your own decision.
Compare the announcement with the conditions in the paper and official documentation.
Sources
Publication dates belong to the source; access dates record when it was checked. Community observations are separate from official statements.
01