Safely Rejecting Redirects in Cloudflare Workers
Learn how to fetch remote assets securely in Cloudflare Workers by configuring manual redirect handling and explicitly rejecting 3xx responses.
Table of Contents7 sections

When writing a Cloudflare Worker that fetches remote assets from third party APIs or origin servers, an outbound request might return a 3xx redirect status code. Automatically following that redirect can bypass internal URL allowlists, leak authorization headers to unintended destinations, and compromise application security. Standard browser or Node.js fetch configurations do not always translate directly to edge runtimes. If you rely on unsupported fetch options or assume the runtime will automatically sanitize redirect hops, your application can fail silently or forward sensitive data to external hosts.
This guide explains how to fetch remote assets securely in Cloudflare Workers by using manual redirect handling, validating your initial targets, and explicitly rejecting unexpected 3xx responses.
The Edge Runtime Redirect Problem
The Fetch API standard defines several modes for handling HTTP redirect responses, including follow, error, and manual. However, edge environments like Cloudflare Workers execute under specific constraints. When an outbound request triggers a redirect, the runtime must decide how to handle the subsequent network hop. Developers often attempt to use options that are either unsupported for outbound Worker requests or behave unexpectedly under specific compatibility dates, causing runtime exceptions before a useful response can be parsed.
Furthermore, if your Worker fetches an asset on behalf of a user, following redirects blindly can lead to Server Side Request Forgery (SSRF) vulnerabilities. If an allowlist permits a safe domain, but that domain issues an HTTP 302 pointing to an internal metadata service or an untrusted external host, an automated redirect will bridge the gap. To prevent this, you must inspect the intermediate response rather than letting the runtime follow it automatically. For a related implementation, see Managing Concurrent Git Commits During Automated.
Validating the Initial URL
Before initiating any outbound network call, your Worker should validate the target URL. Relying solely on string matching is often insufficient because URL parsers can interpret malformed inputs in unexpected ways. Always parse the input string using the global URL constructor and check the protocol and hostname explicitly against a strict allowlist.
function isValidTargetUrl(rawUrl) {
try {
const parsed = new URL(rawUrl);
const allowedHosts = ["api.trusted-domain.com", "assets.trusted-domain.com"];
if (parsed.protocol !== "https:") {
return false;
}
if (!allowedHosts.includes(parsed.hostname)) {
return false;
}
return true;
} catch (error) {
return false;
}
}
By ensuring the initial URL meets strict protocol and host requirements, you establish a secure foundation for the outbound fetch operation.
Implementing Manual Redirect Handling
To prevent the edge runtime from following redirects automatically, pass redirect: "manual" in the options object of your fetch call. When you specify manual mode, any 3xx response is returned directly to your Worker code as a standard Response object instead of triggering a transparent follow sequence.
async function secureFetchAsset(targetUrl) {
if (!isValidTargetUrl(targetUrl)) {
throw new Error("Target URL failed validation checks.");
}
const response = await fetch(targetUrl, {
redirect: "manual",
headers: {
"User-Agent": "SecureWorkerAssetFetcher/1.0"
}
});
if (response.status >= 300 && response.status < 400) {
const redirectLocation = response.headers.get("Location");
throw new Error(`Outbound request attempted a redirect to: ${redirectLocation || "unknown destination"}`);
}
if (!response.ok) {
throw new Error(`Upstream service returned status: ${response.status}`);
}
return response;
}
In this implementation, if the upstream server responds with a 301, 302, 303, 307, or 308, the status check catches the condition immediately. The Worker aborts execution without reading the response body or forwarding sensitive headers to the Location target.
Managing Credentials and Sensitive Headers
When a redirect is followed automatically, runtime clients often propagate authorization headers, cookies, or custom tokens to the new destination. If an untrusted server captures a redirect, it can harvest these credentials.
By keeping redirect handling in manual mode, your Worker maintains complete control over token propagation. If a legitimate business requirement ever dictates that a redirect must be followed, your code must revalidate the new Location URL against your original security policy before issuing a secondary fetch call.
Testing Your Redirect Policy
To ensure your Worker handles various network responses predictably, maintain a small test matrix covering direct successes, redirects, client errors, and invalid URLs.
| Test Case | Initial URL Status | Expected Behavior |
|---|---|---|
| Direct 200 OK | Valid trusted domain | Returns response body successfully |
| HTTP 302 Redirect | Trusted domain pointing elsewhere | Throws error and stops before following |
| HTTP 404 Not Found | Valid trusted domain | Throws upstream status error |
| Disallowed Host | Untrusted domain | Throws validation error immediately |
Adding these verification checks alongside your production fetch path prevents regressions during runtime updates and ensures your edge applications maintain strict security boundaries.
Conclusion
Outbound fetch operations in edge runtimes require deliberate security controls to prevent unintended data exposure and SSRF vulnerabilities. By validating initial target URLs, configuring manual redirect policies, and explicitly inspecting 3xx status codes, you protect your infrastructure from unsafe redirects while maintaining predictable performance at the edge.
Continue Exploring
You Might Also Like

Android Developer Organization Verification Guide
Understand Android developer organization verification, legal-entity checks, and why business verification is an identity boundary rather than an account reset.

Preventing Search Intent Duplicates in Automated Publishing
Learn how automated publishing pipelines can detect search intent duplicates and prevent SEO cannibalization using preflight gates, commit-time checks, and canonical redirects.

Publishing to Medium Without APIs Using Chrome Extensions
Learn how to build a zero-API publishing extension for platforms with deprecated write APIs by leveraging active browser sessions and contenteditable DOM injection.