Stop CDN Bandwidth Abuse with 302 Redirects (No More Surprise Bills)
Every website owner loves the speed boost and scalability of a Content Delivery Network (CDN), but malicious traffic "brushing" (automated abuse of CDN resources) can turn those benefits into hefty bills. In a brushing attack, bad actors repeatedly request your CDN-hosted files (images, videos, etc.) to inflate bandwidth usage and costs. This article explores how to prevent CDN abuse and save on costs. We’ll start with a common (but flawed) solution—embedding an auth key in client-side JavaScript—and then introduce a safer alternative: server-side 302 redirects with an auth key.
The Common Approach: Client-Side Auth Key (Easy but Insecure)
A quick fix many developers try is to embed a secret token or auth key in the front-end code, using it to authorize CDN requests. For example, your page’s JavaScript might include a key and append it to resource URLs (e.g. https://cdn.example.com/file.png?authKey=12345
). This approach is straightforward and keeps casual scrapers out. However, it has serious vulnerabilities and downsides:
- Keys Can Be Extracted: Any secret sent to a user’s browser is effectively public. Attackers can open developer tools or sniff network requests to grab the auth key. As one security discussion put it, “Once the key is client side in any manner it is visible to the user. There is no security possible to keep it safe in the browser.” No matter how you obfuscate or hide it in JavaScript, a determined user can extract it.
- Abuse Is Still Possible: If a malicious bot gets the key, it can hit the CDN directly with automated requests, bypassing your site. The CDN will see a valid key and serve content, racking up your bandwidth usage. In other words, a thief doesn’t even need to “break the lock” if you hand them the key. They can reuse it until it’s invalidated.
- Frequent Key Rotation & Complex Frontend Logic: To limit damage, developers often rotate auth keys frequently or generate one-time tokens. But this means constantly updating the front-end or making the client fetch new keys. It adds complexity to your code and can hurt performance (e.g. if each request needs a fresh token). In fact, using unique query tokens on every request can defeat browser caching – if the URL is always different, the browser won’t cache the file. So you trade off CDN caching benefits for security, which is counterproductive.
- Easy to Spoof Referers: Some rely on referer-based restrictions (only allowing CDN requests that originate from your site), but referer headers can be faked in one line of code. This “hotlink protection” might stop casual misuse, but any script can simply set a bogus referer and still pull from your CDN.
- Still Costly if Attacked: Ultimately, the client-side key approach might keep honest users honest, but it doesn’t stop a serious attacker from running up your CDN bill. For perspective, one developer demonstrated that 1,000 quick requests to a 140 KB image (just re-downloading it in a loop) consumed 140 MB in about a minute – which would cost over $1,000 in a month if sustained! This shows how easily a leaked or spoofed key can be abused to drain your bandwidth.
So, Embedding auth secrets in the front-end is not a robust solution. It’s easy to implement but leaves a gaping hole – whatever is in the user’s JS can and will be discovered. Continuously changing keys and tinkering with front-end logic is a brittle game of whack-a-mole. We need a better way to protect CDN content that doesn’t rely on the honor system or constant manual updates.
A Better Alternative: Server-Side 302 Redirect with Auth
Instead of giving the client a key to access the CDN, keep that key and logic on your server. The idea is to have your server act as a gatekeeper: the client requests the resource from your server, and then your server responds with a HTTP 302 redirect (a temporary redirect) to the actual CDN URL, including an auth token or signature. This way, the browser is automatically sent to the CDN to fetch the content, but only after your server has decided it’s OK.
Here’s how this flow works step by step:
- Client Requests the Resource from Your Server: On your webpage, instead of pointing directly to the CDN, you point to a URL on your own server (e.g.
https://mysite.com/get-file/123
). This URL doesn’t serve the file itself; it will handle the auth and redirect. - Server Checks and Generates Auth: When the request hits your server, you perform your security logic server-side. Because it’s your code on the backend, you have full control. For example, you can check the user’s session, IP address, region, request frequency, etc. This is the time to apply rules: if an IP has hit too many requests, you could decide not to serve it; if the user is from a banned country or on a watchlist, you can block or challenge them; if everything looks good, you proceed. The server then generates a one-time or short-lived signed URL or token for the actual file on the CDN (using a secret key that only the server knows).
- Server Responds with a 302 Redirect: Instead of returning the file, your server responds with “HTTP 302 Found” and a Location header pointing to the CDN URL of the file. For instance, the redirect Location might be
https://cdn.example.com/path/file.png?token=XYZ
. That token XYZ is the auth key or signature your server just created. Importantly, this token never appears in any JavaScript – it’s only in this server response. - Browser Follows Redirect to CDN: The user’s browser automatically follows the 302 redirect (browsers do this for any 30x redirect by default). Now the request goes to the CDN URL along with the token. The CDN (or cloud storage) validates the token (ensuring it was signed by your secret and not expired). If valid, the CDN serves the file to the browser. From the user’s perspective, the image or video still loads via the CDN, so it’s fast.
- Content Delivered, with Control: The content is delivered from an edge location as usual, but only after the server allowed it. The heavy lifting (the bytes of the file) are still coming from the CDN, not your origin, so you preserve the performance and offloading benefits of the CDN. However, any client that tries to skip your server and go straight to the CDN will fail, because they won’t have a valid token.
This approach dramatically improves security and flexibility:
- Auth Stays Hidden: The signing key or auth logic never touches the client. Attackers can’t simply view-source or intercept a script to get in. Even if they capture one redirect URL, the token in it can be made short-lived or single-use. They would have to repeatedly query your server to get new tokens, which you can detect and block. Essentially, you’ve moved the vulnerability from an exposed front-end to a protected back-end (where you have more tools to handle it).
- Server-Side Control: Because the request comes to your server first, you can implement fine-grained control. For example, you can allow or deny requests based on geolocation (country or even city), enforce rate limits per IP or per user, require the user to be logged in, or check a CAPTCHA solution – whatever security logic you need. All of this happens before any bandwidth is consumed on the CDN. If something is off, you simply don’t issue a redirect (or issue a redirect to a small “error” page), and that potentially saves you from serving gigabytes of data to a bot.
- Dynamic Routing (Flexibility): Your server can decide different redirect destinations for different scenarios. Say you have users in China and elsewhere: you might host files in Alibaba Cloud OSS for China users (to comply with regulations and improve speed) and in Cloudflare R2 for global users. The server can detect the user’s region and send a 302 redirect to
oss-cn-example.aliyuncs.com/…
for Chinese IPs or tocdn.cloudflare.com/…
for others. You could even have multiple CDN providers or storage backends (e.g. redirect video files to a video-optimized CDN, images to another). This is all transparent to the client – they just hit your endpoint and get sent to the best location. Different content types can also be handled uniquely: e.g., if a request is for a thumbnail image vs. a full image, the server could redirect to different paths or buckets. This level of flexibility is hard to achieve with a purely client-side scheme. - No Front-End Changes Needed: If you ever need to change how auth works or switch CDN providers, you can do so entirely on the server. The client’s code (just requesting
mysite.com/get-file/123
) stays the same. No redeploy of front-end, no exposing new keys. For example, if a token might be compromised or you want to rotate secrets, you update the server config and it takes effect immediately for the next request – users don’t notice anything except maybe a one-time redirect delay. This greatly simplifies maintenance. - Minimal Performance Impact: The extra step (the 302 redirect) is a very lightweight HTTP response and adds just one quick round trip to your server. The file still comes via CDN, so 99% of the bandwidth and latency is handled by the CDN edge. In practice, the user might not even notice the redirect. CDNs and browsers handle 302s efficiently (browsers automatically follow them without user intervention). And because it’s a temporary redirect, browsers typically won’t cache it permanently, so you can keep control (the next request will still come to your server for fresh authorization unless you choose to set a cache header).
- SEO Considerations: Using a 302 (temporary) redirect in this manner is SEO-friendly. Search engines understand 302s as non-permanent, meaning they will keep the original URL indexed and not treat the content as moved permanently. In other words, your SEO “juice” remains with your site. Experts note that a 302 redirect ensures the original page retains its SEO value and Google ranking, whereas a 301 might transfer it to the CDN URL (which you don’t want). So, you can safely use 302 redirects for resource delivery without harming your search rankings. The CDN URLs won’t get indexed as the canonical source of content; your site remains the primary source in the eyes of Google. (It’s still wise to use proper
<link rel="canonical">
tags on pages if needed, but for static resources this is usually a non-issue.)
To visualize the difference between the two approaches, let's compare them side by side:
On the left , the client-side key approach is shown: the browser loads a page that contains a JavaScript auth key, then uses that key to request content directly from the CDN. The content is delivered, but an attacker can easily extract the key from the page or network requests and abuse it by scripting repeated CDN calls , racking up costs (as indicated by the red dashed arrows). On the right , the server-side 302 redirect approach keeps the key hidden on the server. The browser asks the web server for the resource, and the server responds with a 302 redirect (temporary redirect) including a one-time auth token in the URL. The browser then fetches from the CDN with that token, getting the content. In this model, the server can enforce security checks (e.g., block malicious bots making mass requests), and the client’s code remains simple.
Conclusion: CDNs Are Worth It—Just Protect Them
Should you avoid using a CDN because of abuse risks? Definitely not. CDNs are extremely valuable for speeding up content delivery and reducing load on your servers. They bring content closer to users and can even lower costs if used wisely (serving cached content cheaply). The solution is not to abandon CDNs, but to fortify them.
By implementing measures like server-side redirects with auth (and other best practices like CDN rate limiting or WAF rules), you ensure that your CDN works for you and your users, not for attackers. Malicious traffic brushing can be stopped in its tracks, saving you potentially huge bandwidth charges and service slowdowns. Meanwhile, real users still get the fast, smooth experience they expect.
In summary, use a CDN, but don’t leave it wide open. Combine it with smart server-side controls: keep your auth keys secret, decide who gets access to what, and leverage HTTP redirects to seamlessly route users to the right content. This way, you can enjoy the performance benefits of a CDN safely and cost-effectively. With a bit of upfront effort in setting up these protections, you’ll sleep easier knowing that both your website and your wallet are safeguarded from malicious traffic.