All articles
AI News

AI Bot User-Agent Spoofing: How Attackers Evade WAFs During Mass Scans

FDE Coach EditorialAugust 14, 20269 min read

The Signal: What Actually Happened

Data from Known Agents revealed a sharp, anomalous spike in traffic purporting to be from legitimate AI crawlers. The user-agent strings—ClaudeBot, GPTBot, PerplexityBot—looked correct. The IP addresses did not. These weren't the documented, reverse-DNS-verifiable origin servers of Anthropic, OpenAI, or Perplexity. They were random VPS endpoints, residential proxies, and Tor exit nodes firing off requests at a rate no polite crawler would ever use.

The payload told the real story. These requests weren't fetching robots.txt or politely indexing public content. They were probing for exposed .env files, testing authentication bypasses on admin panels, and iterating through known CVEs in popular WordPress plugins. Someone had weaponized the reputation of AI bots to run a mass vulnerability scan.

This isn't a theoretical attack. It's a live, observable shift in how opportunistic attackers are routing around simple user-agent-based allow/block rules. The core insight is brutally simple: if your WAF or rate limiter has an implicit trust relationship with a user-agent string, you've handed over a skeleton key.

The Anatomy of a Spoofed Scan

To understand the attack, you need to see the full request context. A legitimate ClaudeBot hit looks something like this:

GET /blog/rss-newsletter-agent-cron-cloudflare-workers HTTP/1.1
Host: fdecoach.com
User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ClaudeBot/1.0; +https://www.anthropic.com/claude/bot
Accept: */*

A spoofed probe, in contrast, carries the same user-agent but targets a completely different surface area:

GET /.env HTTP/1.1
Host: fdecoach.com
User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ClaudeBot/1.0; +https://www.anthropic.com/claude/bot
Accept: */*

The request path is the smoking gun. No legitimate AI crawler scans for environment files. The attack pattern is a classic spray-and-pray: hit every domain in a target list with a common wordlist of sensitive paths, but dress the request in a user-agent that many security teams have explicitly allowlisted to avoid blocking AI-driven traffic that might benefit their SEO.

The Full Flow

Here's how the scan infrastructure typically chains together:

The attack succeeds because the decision gate at the WAF layer uses a single, easily forged signal to classify the traffic as benign.

Why This Bypass Works: The Trust Paradox

Engineers have been conditioned to treat certain user-agents as trustworthy. This makes sense in a world where Googlebot's traffic directly correlates to search visibility. Blocking a legitimate AI crawler could theoretically impact how your content surfaces in AI-powered search summaries. The business pressure to keep these crawlers unblocked is real.

The problem is that the user-agent header is fundamentally a client-supplied, unauthenticated string. Relying on it for any security decision violates a core principle: never trust input you haven't verified through an out-of-band channel.

Here's the trust model most teams are running implicitly:

SignalTrust LevelReality
User-Agent string matches known botHighTrivial to spoof
Request path is /robots.txtMediumLegitimate bots fetch this first
Request path is /wp-adminLowImmediate block candidate
IP reverse-DNS matches bot's domainVery HighHard to spoof, rarely checked

The gap between "User-Agent matches known bot" and "IP reverse-DNS matches bot's domain" is where the mass scan operates. Most teams stop at the first check.

Practical Detection Engineering: Finding the Fakes

You don't need a vendor solution to start catching these. If you've got access to your edge logs, you can write detection logic today. The goal is to find requests where the user-agent claims to be a known crawler but the behavior or origin doesn't match.

Step 1: Verify the IP

Legitimate AI crawlers publish their IP ranges or have reverse-DNS entries that map back to their domain. For ClaudeBot, the reverse-DNS should resolve to a hostname under anthropic.com. For GPTBot, it's openai.com. Write a quick verification script:

import socket

def verify_bot_ip(ip: str, expected_domain: str) -> bool:
    try:
        hostname, _, _ = socket.gethostbyaddr(ip)
        return hostname.endswith(expected_domain)
    except socket.herror:
        return False

# Example: Check if an IP claiming to be ClaudeBot actually belongs to Anthropic
if not verify_bot_ip(request.ip, "anthropic.com"):
    log_and_flag(request)

This check is fast, runs inline, and catches the vast majority of spoofed traffic. Residential proxy IPs won't resolve to anthropic.com. Neither will random VPS instances.

Step 2: Rate and Path Analysis

Even without IP verification, the request pattern gives them away. A legitimate crawler has a characteristic rhythm: it fetches robots.txt, respects Crawl-Delay directives, and spreads requests across your entire site. A vulnerability scanner hammers a specific set of paths at high frequency.

Set up a simple heuristic in your log pipeline:

SELECT 
    client_ip,
    user_agent,
    COUNT(*) as request_count,
    COUNT(DISTINCT request_path) as unique_paths
FROM edge_logs
WHERE user_agent LIKE '%ClaudeBot%'
  AND timestamp > NOW() - INTERVAL '5 minutes'
GROUP BY client_ip, user_agent
HAVING request_count > 100 
   OR unique_paths < 3;

A real ClaudeBot will show moderate request counts across many unique paths. A scanner will show high counts concentrated on a handful of sensitive endpoints.

Step 3: Challenge Suspicious Sessions

When you flag a session as suspicious, don't just block it—that teaches the attacker which IPs you've identified. Instead, issue a silent challenge. Drop a cookie requirement or inject a JavaScript challenge. Legitimate crawlers don't execute JavaScript and won't be affected. Automated scanners using raw HTTP libraries will fail the challenge, and you can log the failure without tipping your hand.

Building a Low-Friction Defensive Layer

If you're running a production workload, you need this logic baked into your edge layer. The architecture is straightforward:

This adds a single reverse-DNS lookup to the hot path for bot-claimed requests. The latency cost is minimal if you cache the results. A local in-memory cache with a 1-hour TTL for verified IPs keeps the overhead near zero for repeat visitors.

For teams building custom detection pipelines, this same pattern applies whether you're processing edge logs in a Gemini-powered sentiment dashboard or routing traffic through a Cloudflare Worker. The verification step is the same; only the integration point changes.

The Offensive Engineer's Perspective

Understanding the attacker's tooling makes the defense obvious. Most mass scanners are built on tools like nuclei with custom user-agent flags or simple Python scripts using the requests library. The attacker's workflow is:

  1. Generate a target list (Shodan searches, certificate transparency logs, DNS brute-force)
  2. Load a wordlist of sensitive paths (.env, .git/config, /wp-json/wp/v2/users)
  3. Set User-Agent: ClaudeBot/1.0 in the request header
  4. Route through a proxy pool to distribute the source IPs
  5. Parse responses for secrets, version headers, or exposed configuration

The entire operation hinges on step 3 being enough to bypass the first layer of defense. As a forward deployed engineer, you can replicate this exact workflow in a controlled red-team exercise. Build a job application autofill extension or a personal finance categorizer first to get comfortable with shipping artifacts that touch external APIs. The same request-manipulation skills apply directly to security testing.

A Balanced Take: The Real Risk

This isn't a sophisticated APT technique. It's a low-effort, high-reward tactic that works because the defense community has been slow to update its mental model around AI crawlers. The risk is amplified by the fact that many organizations have explicitly added allowlist rules for these user-agents in the last 12 months without adding the corresponding verification step.

The fix isn't to block AI crawlers. The legitimate ones provide value, and the business case for allowing them is sound. The fix is to stop treating the user-agent string as an identity assertion and start treating it as an unverified claim that requires corroboration.

For FDEs specifically, this is a perfect interview signal. When you're preparing for the FDE interview loop, being able to walk through this exact scenario—"How would you detect and mitigate AI bot spoofing?"—demonstrates the kind of practical, systems-level thinking that separates signal from memorization. It shows you understand the trust boundaries in distributed systems and can design defenses that work in production, not just on a whiteboard.

FAQ

Q: Can't I just block any request with a path like /.env regardless of user-agent? Yes, and you should. A well-configured WAF should have path-based rules that catch common sensitive-file probes. The user-agent spoofing becomes an issue when your WAF has an allowlist rule that skips those checks for certain user-agents. The attack exploits the ordering of your rule evaluation.

Q: What's the performance impact of reverse-DNS lookups on every request? Non-trivial if done synchronously on every request. Cache aggressively. Verified bot IPs rarely change. A 1-hour cache with a fast fallback (treat cache misses as unverified) keeps the 99th percentile latency under 5ms.

Q: Are residential proxy IPs ever going to reverse-DNS to a legitimate bot domain? No. Residential proxy providers use consumer ISP IPs. These will never have reverse-DNS entries pointing to anthropic.com or openai.com. This makes the reverse-DNS check extremely high-signal.

Q: What if the attacker uses the actual IP ranges of a legitimate bot? That's a fundamentally different, much harder attack. It would require compromising the bot's infrastructure or running a man-in-the-middle between the bot and your server. At that point, you're not dealing with a mass vulnerability scanner; you're dealing with a targeted adversary, and your threat model should adjust accordingly.

Q: Should I share this intelligence with my team? Absolutely. The Known Agents data is public, and the detection logic is straightforward to implement. The fastest way to close this gap is to add a reverse-DNS verification step to your existing bot management rules and share the before/after metrics with your security team.

#security#bot-detection#user-agent#devops

Want to build like a Forward Deployed Engineer?

FDE Coach is a cohort-based program in frontend, backend, AWS, and AI. Build real products and get referred to 200+ hiring partners.

Explore the program

More ai news

August 15 · 0d left
Enroll Now