---
title: "JS Detections: the one Pro-tier Cloudflare lever that actually catches HTTP-replay proxies"
canonical: https://dxdev.com/blog/js-detections-pro-tier-lever-residential-proxy/
datePublished: 2026-05-04
---
A known hostile proxy operator was pushing 224k requests a day straight through to my origin, and Cloudflare's Pro-tier bot rules never laid a finger on it. The reason was simple: it relays raw HTTP through real residential IPs with rotating real browser User-Agents, so there is no signature to match and no datacenter range to ban. It looks like a thousand iPhone users from Germany. Then I flipped one toggle in Super Bot Fight Mode, JS Detections, and within two hours the blocks across the board jumped hard: total security events up 56 percent, custom-rule hits more than doubled. Some of that jump belongs to a geo block I shipped in the same window, and I will get precise about which lever did what.

## The traffic that walked through every rule

I run an old ASP Classic SaaS on Windows, IIS and classic ASP, and I had just put Cloudflare in front of it. On the Pro plan, the bot tooling you get is real but modest. Super Bot Fight Mode gives you a Definitely-Automated toggle (Allow or Block), Verified bots (Allow), JS Detections (a toggle), and Static Resource Protection (which stays greyed out until JS Detections is on). There is no "Likely Automated" tier, that is Enterprise only. The `matches` regex operator is Enterprise too, so on Pro your custom rules get `contains`, not regex. Rate-limit periods bottom out at 10 seconds.

For most abusive traffic that toolkit is enough, because most abusive traffic lies in a way you can detect. A scraper forging `Googlebot` in its User-Agent does not match Cloudflare's verified-bot signal, so you catch it. A scanner hammering one path from one ASN trips a rate limit or a custom rule. The managed ruleset handles the obvious automated stuff.

The residential-proxy operator did none of that. ASN 200373, "3xK Tech GmbH," was already on my radar: five /19 ranges of it had been firewall-blocked at the origin for account enumeration scraping. But behind Cloudflare it was a different fight. CF's signature-based managed rules only catch bots that carry a signature in the User-Agent, and this operator carries real Chrome and Safari strings that rotate per request. So 224k requests a day sailed through to origin. Its setup strips the detection surface down to almost nothing:

- The IPs belong to real residential ISPs, so IP and ASN reputation rules see normal home connections, not a datacenter.
- The User-Agent is a real browser string that rotates per request, so UA rules and managed-bot signatures have nothing stable to grab.
- There is no JavaScript engine in the loop at all. The proxy is an HTTP relay. It receives a request, forwards it, returns the response. It does not parse, it does not render, it does not execute.

That last point is the whole game, and at first I treated it as the bad news. It is actually the opening.

## Why a JS challenge is the right move

Every rule I had been reaching for discriminates on something the proxy controls: which IP it comes from, what string it puts in the UA header, how fast it sends requests. The operator can spoof or distribute all of those. Fighting on that ground is a losing arms race, because you are trying to out-pattern an adversary who owns the patterns.

A JavaScript challenge moves the fight onto ground the proxy cannot fake. JS Detections injects a small invisible JavaScript challenge (on the order of a kilobyte) into page responses. A real browser executes it silently and the visitor never sees a thing. The result feeds back as a signal that says "yes, a real JS runtime ran here." An HTTP-replay proxy receives that challenge as inert bytes in the response body and does nothing with it, because it has no engine to run it. The challenge never gets satisfied. That missing signal is what Super Bot Fight Mode then escalates on.

The challenge discriminates on a capability, not a claim. UA and IP rules ask "what do you say you are," which a proxy answers with whatever you want to hear. A JS challenge asks "can you run this," which a raw HTTP relay cannot, no matter how many residential IPs it owns or how cleverly it rotates its headers.

## Watching it work in real time

I turned JS Detections on mid-session and came back to the 24h Security Events aggregate about two hours later. The numbers had moved hard (this was JS Detections plus a geo block I shipped in the same window, so read it as the combined effect, not JS Detections alone):

- Total security events: 17.36k climbed to 27.08k, a 56 percent jump.
- Block actions: 11.89k climbed to 17.61k, about 48 percent more blocks.
- Custom-rule hits: 7.74k climbed to 16.64k, more than doubling at +115 percent.

The mechanism behind those numbers is worth being precise about. JS Detections by itself is not the thing issuing the blocks. What it does is feed more signal into the system, so traffic that was previously ambiguous now reads as clearly automated, which makes the existing rules (Super Bot Fight Mode, plus my own custom rules) fire on traffic they had been letting slide. The challenge does not replace your rules, it sharpens the input they run on. That is why the custom-rule hits more than doubled at the same time: the same rules, suddenly seeing the traffic for what it is.

The clearest single example was not the residential operator at all. The top blocked IP was a US-based scraper (so geo-blocking was irrelevant to it), and it jumped from 2.57k to 5.99k blocks. That IP more than doubled because JS Detections plus my empty-User-Agent rule started catching it reliably instead of letting it slide. That is the lever working exactly as advertised on an HTTP-style scraper.

I want to be honest about the residential operator specifically, because this is where it gets less clean. My plan was to filter Security Events by ASN 200373 and watch its block count climb from zero. What actually happened is that 3xK dropped out of the top five ASNs entirely. I could not cleanly attribute that to JS Detections, because the geo block landed in the same window and 3xK was running out of Germany, so the geo rule could have caught it, or the operator could have simply backed off once the volume stopped paying. The aggregate result was what I wanted, but I did not get a clean per-ASN "blocks climbing from zero" confirmation for that one operator. The US scraper's numbers are the better evidence that the JS challenge does what I claimed.

## A side effect worth knowing

Flipping JS Detections on also un-greyed two toggles that had been locked: Static Resource Protection and the Optimize-for-WordPress option. These features need the JS challenge active to function, so if you have been staring at a greyed-out Static Resource Protection toggle wondering why you cannot enable it, turn on JS Detections first. The one real trade-off: JS Detections injects script into every page response, so any legitimate non-JS client you care about (link-preview fetchers, some monitoring, anything genuinely headless you want to allow) is going to look the same as the proxy to this signal. Carve out verified bots separately, and watch what the challenge starts catching rather than flipping it and walking away. The lesson generalizes past Cloudflare: when an adversary owns every signal your rules read, stop matching claims and start testing a capability it cannot fake.

## Related

- [The 3% bot attack that took the site down: why your IP blacklist can't see residential proxies](/blog/residential-proxy-swarm-blacklist-cant-see/): why signature-based rules fail against this operator class
- [Bot Swarm Detection: The Three-Signal Triangle That Catches What IP Reputation Misses](/blog/three-signal-triangle-bot-swarm-detection/): the broader detection framework for residential proxy swarms
- [Cloudflare Pro is a box of levers, not a managed service](/blog/cloudflare-pro-tools-to-configure-not-managed/): the full Pro toolkit and how to configure it deliberately
- [Geo-blocking everywhere except the US and Canada, and the one clause that saves your SEO](/blog/geo-block-by-customer-base-verified-bot-clause/): complementary Cloudflare rules layered on the same Pro setup
- [Operator, not IP: fingerprinting a 40,000-IP proxy swarm by its RIPE maintainer](/blog/operator-not-ip-fingerprint-ripe-maintainer/): identifying the same operator class at the network level
