~/peter-pagenstedt

notes on software, systems, and captchas

2026-06-04

the rise of vibe-coded anti-bot systems

A look inside the wave of LLM-built anti-bot systems, using Fastly and Apple as examples.

This article has been written over the course of a few weeks. Information could be outdated, but was accurate at the time of writing. Anti-bots are normally a fast-changing topic. If you are from Apple or Fastly, please don't hesitate to reach out for whatever reason.

Introduction

With the rise of powerful LLMs, more and more companies are asking themselves if they should "build or buy" software. A lot of small services, which would be easier to buy than to build in-house a few years ago, can now be developed with a single Claude Code session.

There are many great articles about this topic which I don't want to repeat. I want to look at one specific service, which is the "anti-bot" service. There are a number of different companies that will sell you this as a service, from giants like Google ReCaptcha, Akamai and Cloudflare, to smaller ones like DataDome and Kasada. These are expensive though, and can be hard to integrate. Also, most managers probably don't understand why you should buy one if you can just get a few engineers to vibe-code an "equivalent" service in a week.

Examples

I want to show what can happen if you decide to go down that path with two examples from big companies:

  1. Apple Discussions interstitial page (example)
  2. The Fastly interstitial page (example)

These are similar, but while Apple only vibe-coded their own anti-bot, Fastly made it into a product it's selling!

But how do I know these systems are largely written by AI?

I reverse-engineered both and built a fully request-based solver for each. This is intended for learning and research purposes only. If either company has a problem with this, please reach out to me.

Apple

Inside the Apple source code, we see lovely snippets like this:

_0x65ae2f.push({
  'type': "generic_canvas",
  'severity': 0x4,
  'description': "Canvas fingerprint too generic",
  'detected': this.hasGenericCanvas(_0x3c91c6)
});

For anyone unaware: having a description and severity inside your client-side anti-bot scripts is not the smartest move, and not something most humans would do.

    static ["analyze"](_0x9abf83) {
      const _0x4da7ac = [];
      let _0x166d37 = 0x0; // <-- This is the score variable initialized to 0

      // ... [It calls checkAutomation, checkConsistency, etc. and pushes to _0x4da7ac] ...

      // 1. Filters only the signals that were actually detected
      const _0x4a5a30 = _0x4da7ac.filter(_0x597be5 => _0x597be5.detected);
      
      // 2. THIS IS THE SCORING MATH: Sums it up and multiplies severity by 10
      _0x166d37 = _0x4a5a30.reduce((_0x3c4fc3, _0x3e06f0) => _0x3c4fc3 + _0x3e06f0.severity * 0xa, 0x0);
      
      // 3. Caps the max score at 100 (0x64 in hex)
      _0x166d37 = Math.min(0x64, _0x166d37);
      
      // 4. Calculates "LOW", "MEDIUM", or "HIGH" risk based on the score
      const _0x127532 = this.calculateRiskLevel(_0x166d37);
      
      return {
        'score': _0x166d37,
        'signals': _0x4a5a30,
        'riskLevel': _0x127532,
        'details': {
          'totalSignalsDetected': _0x4a5a30.length,
          'highSeveritySignals': _0x4a5a30.filter(_0x2c42a9 => _0x2c42a9.severity >= 0x8).length,
          'automationDetected': _0xa580f5.some(_0x2d71ac => _0x2d71ac.detected),
          'inconsistenciesFound': _0x1a831d.some(_0x24de8f => _0x24de8f.detected)
        }
      };
    }

The script that is doing the fingerprinting is barely obfuscated (they use the open-source javascript-obfuscator). The script collects a lot of data it never sends, and generates a trust score client-side. This defeats the whole purpose — it's like having a "yes I paid, trust me bro" header on a checkout page. An attacker does not need to perfectly spoof a complex WebGL environment; they simply need to monkey-patch or override the final analyze return object to look like a clean device session. Oh, and Apple uses this same system on their checkout page.

Error messages and debugging logs are left in the source code. It can be defeated by a ~50 LoC Node.js solver. It contains a simple proof-of-work challenge, which can be solved very fast on modern hardware, I have open-sourced a solver. This was likely built to prevent mass-scraping of their forums for LLM data, but it doesn't actually achieve that. LLM data scrapers can and will bypass it.

Fastly

Fastly's anti-bot is a tiny bit better. It collects some browser data; however, that data doesn't seem to be checked on the backend. Like Apple, it does a simple proof-of-work challenge. It also sends its payload in plaintext back to Fastly's backend, which simplifies reverse-engineering it a lot.

// ....
  "distinctiveProps": {
    "value": {
      "awesomium": false,
      "cef": false,
      "cefsharp": false,
      "coachjs": false,
      "fminer": false,
      "geb": false,
      "nightmarejs": false,
      "phantomas": false,
      "phantomjs": false,
      "playwright": false,
      "rhino": false,
      "selenium": false,
      "webdriverio": false,
      "webdriver": false,
      "headless_chrome": false
    }
  },
// ....

However, they haven't updated their system for at least 8 months now, meaning my open-source solver still works exactly as it did on day one. I would forgive them if it were only an internal tool, but for a SaaS that should protect customers, this is pretty embarrassing. This is not the best decision in a cat-and-mouse game, like web scraping is (especially when people like me publish solvers for your system!)

Conclusion

It seems like for both Apple and Fastly, Claude suggested a PoW challenge and the collection of some trivial, public device fingerprints. The implementation of Fastly's is better (at least scores are not computed client-side), however Fastly doesn't seem to have anyone maintaining it. Both of these might stop the most trivial of scraping, but won't stop anyone who is determined enough. Especially for Apple, which already uses Akamai - whose offering includes anti-bot. I don't understand why they opted to build their own system. Akamai, just like Cloudflare, Kasada and others, have teams that know what they are doing. Of course they aren't perfect either and can be solved, but they won't let an open-source solver solve their challenges for 8 months without updating their system.

On the flip side, a bigger variety of anti-bots will also be more difficult for attackers. While there are a lot of paid services to bypass any big commercial anti-bot system, there aren't any services selling solutions for Fastly or Apple. I plan on writing more articles about topics I glossed over today - for example, what can or cannot be done against LLMs being used to solve anti-bot challenges, how "actual" anti-bot services operate, and how detection can be done on the network level instead of in the browser.