Bot Blocking Isn't One Header — Five Layers, Seen from the Site's Side
Connection, request, page, input and session are checked for one consistent story, then scored
When I heard Reddit and Naver were keeping browser-driving AI out, my first guess was "they check the User-Agent header." Looking into it, that's not it. Modern bot management doesn't look at one header; it checks whether signals from several layers agree, and scores the request. This is written from the site operator's side, the side doing the blocking. It shows what to decide first when you add bot protection to your own service.
The picture people imagine, and the real one
imagined: request ── User-Agent ──▶ allow / block
In practice the front end looks at several layers. The figure follows the structure Cloudflare documents publicly; other providers may differ.
| Layer | What it looks at | Signal for the defender |
|---|---|---|
| Connection | TLS ClientHello fingerprint, HTTP/2 settings | script HTTP clients and real browsers differ from here on |
| Request | header set and order, client hints, sec-fetch-* |
if the UA names one browser and other headers point to another, the mismatch is a signal |
| Page | the browser environment as seen from JavaScript | traces of headless or automation tools |
| Input | whether clicks and keys are real input | events generated by scripts |
| Session | IP reputation, request pacing, account history | behavior adds up even if each request looks clean |
Changing the User-Agent touches one cell in the second row. If the other layers tell a different story, the score stays.
Scores run from 1 to 99
Per Cloudflare's bot score docs, scores go from 1 to 99, and lower means more likely automated. The engines are heuristics (matching known fingerprints), machine learning, and JavaScript detections. A request the heuristics are sure about gets a 1.
The best-known connection-layer signals are TLS fingerprints like JA3 and JA4. JA4 improves on JA3 by sorting the ClientHello extensions. Granular scores and JA3/JA4 values are visible only to Enterprise customers who bought Bot Management; Pro and above see grouped "automated / human" buckets.
Passing once isn't the end. In an August 2026 blog post Cloudflare described detection that watches client behavior for the whole session. A CAPTCHA guards a moment; a behavior score watches what comes after.
Reddit narrowed the doors, not the headers
As reported by The Verge (2026-09-30), Reddit's explanation: Old Reddit requires login and keeps only accounts active within the six months before the switch. RSS ends on 2026-11-13. The stated reason is large-scale scraping and automated abuse.
That isn't "filter the AI browser header." It's closing doors and narrowing accounts. From the defender's side it's the cheapest move. The fingerprint race never ends; closing an anonymous entry point is done once.
For Naver I found no public document saying "this header means an agent browser." Yeti is the name of Naver's outbound crawler, not a marker for filtering incoming browsers. I couldn't confirm which layer Naver uses, so I'm not claiming one.
For your own service: what, and when
| Situation | Do this first |
|---|---|
| automated attempts flood login or sign-up | rate limits and a CAPTCHA |
| someone scrapes your public API or RSS | move it behind auth, or issue keys |
| browser automation posing as people | take the front-end bot score (Cloudflare etc.) and write rules on it |
In Rails, the first row starts with one line in a controller: rate_limit, available since Rails 7.2.
class SessionsController < ApplicationController
rate_limit to: 10, within: 3.minutes, only: :create
end
A User-Agent blocklist alone guards the weakest cell. It's useful for sorting out crawlers that honestly say who they are. Anyone trying to hide changes that cell first.
What I didn't do: I didn't send automated browsers to Reddit or Naver to see which layer rejects them, and the score weights aren't public.
If you're deciding how much bot and scraping protection your service needs, or how to split login and API entry points, ask us at https://www.negabaro.com/contact.
How It Works
Connection: TLS ClientHello and HTTP/2 settings reveal the client type
Request: check that header order and client hints agree with the UA
Page and input: JavaScript checks the environment and the events
Session: IP, pacing and account history add up to a 1-99 score: allow, challenge or block