Today you will learn how to block Proxy IP’s (free ones) using Cloudflare Workers for Free.

As you already know by now, Cloudflare offers Managed Lists . These are available only for Enterprise customers.

Their Managed Lists are more effective than what we are doing here, but nevertheless our method is decent considering it’s Free.

For an added bonus, you can customise the returned “blocking” page to flex off with your custom security 😁

Why Block Proxies?

I have been questioned on my other post by some people like “why on earth would you block TOR?”. Same as with TOR, these Proxies are always abused.

They are abused to create multiple fake accounts, abuse promotions, attempt hacking, scraping and much more. If you are serious about your website, you should block Proxies. Especially if you have a small commerce shop for example.

I would also like to mention that because these Proxies are used for scam, spam and other things, they have a bad reputation. Traffic coming from bad reputation IP’s harm your SEO .

Blocking Free Proxies

As explained in my other article on blocking TOR, this is extremely similar. We have a worker that stores Proxy IP’s in Workers KV and you simply query them.

The only major difference is that we do not have a specific or reliable API to get these Proxy IP’s, so we must scrape them or download them where we can.

Using a combination of scraping and downloading Proxy IP lists, we can achieve this goal completely free (well, almost free).

Service worker

I have prepared a ready to use worker for you on Github .

All you have to do is clone it, configure the requirements and publish it.

Easy Configuration

To setup this worker please refer to my other article (because I do not want to duplicate content):

The worker is configured to run every 10 minutes, if you want to change this just edit wrangler.toml.

Longer periods will reduce your monthly Workers usage, but will not be as effective because these free Proxy IP lists update around 10 minutes on average.

It is recommended to update the list as often as possible to ensure abusers of free Proxies are caught.

Easy Usage

Exactly as we do it in my other post on blocking TOR, the usage is the same. With the difference that now that KV namespace is called PROXIES_COMBINED_LIST and the cache is set to just 2 minutes.

Below a simple starter script that you can simply copy and paste into a new or existing worker:

 1const clientIP = request.headers.get('CF-Connecting-IP');
 2const ipset = await PROXIES_COMBINED_LIST.get("ipset", { type: "json", cacheTtl: 120 });
 4if (ipset[clientIP]) 0
 6return new Response("Proxies are Forbidden", { 
 7  headers: {
 8	'content-type': 'text/html;charset=UTF-8',
 9  },
10  status: 403


Much like the other post (again, I do not want to duplicate content), I am giving you a simple ready to use starter worker:

 1addEventListener("fetch", event => {
 2  event.respondWith(handleRequest(event.request))
 5const html = `<!doctype html>
 6<html lang="en">
 7  <head>
 8    <title>Access Denied</title>
 9    <meta charset="utf-8">
10    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
11    <meta name="robots" content="noindex, nofollow" />
12    <meta name="viewport" content="width=device-width, initial-scale=1">
13    <link href="[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> 
14  </head>
15  <body>
16    <div class="container">
17      <h1 class="mt-5 text-center">Oops!</h1>
18      <h2 class="mt-2 text-center text-danger">Proxies are not allowed.</h2>
19    </div>
20  </body>
23async function handleRequest(request) 
25  const clientIP = request.headers.get('CF-Connecting-IP');
26  const ipset = await PROXIES_COMBINED_LIST.get("ipset", { type: "json", cacheTtl: 120 });
28  if (ipset[clientIP]) 
29  {
30    return new Response(html, { 
31      headers: {
32        'content-type': 'text/html;charset=UTF-8',
33      },
34      status: 403
35    });
36  }
38  const response = await fetch(request);
40  return response;

Don’t forget to add the KV Binding to this worker.

With the above worker deployed we fire up the Chrome, grab a free proxy, configure Proxy SwitchyOmega and test:

Block Proxy Result

As you can see, it works exactly as expected. Proxy IP’s blocked, well at least the free ones we could find.

It is important to note that paid proxies are not blocked since we do not have access to them, but if you are willing to subscribe to them you can do so.

But it’s also important to know that you can add more websites/api’s to scrape and download from.


In my other post I have explained the strategy used in these workers to minimize costs as much as possible, this worker is no different.

However, due to the fact that we need to update the list more often the usage changes to: 6 WRITE(s) x 24 HOUR(s) = 144 WRITE(s) per Day, ending up in 4464 WRITE(s) per 31 Day(s).

Unfortunately that’s not enough to “fit” into the Free limit of Workers, so I strongly suggest you invest $5/month to upgrade. You will then have 1,000,000 (one million) WRITE(s) limit.

If you are not happy to do that, you must sacrifice usage and decide if you wish to block just TOR or Proxies. Blocking TOR already “fits” into the Free limits, but Proxies will not; so you would need to change the cron time to 1 Hour from 10 minutes for proxies.

Again, I strongly recommend you to upgrade so you can use both workers.

Well that’s it, I hope this article and tool has helped you.

Let me know your thoughts!