JA3 computes an MD5 hash from fields in the TLS ClientHello message: the TLS version, cipher suites, extensions, elliptic curves, and elliptic curve point formats. Because each TLS library (OpenSSL, BoringSSL, NSS) produces a distinct combination of these fields, the resulting hash reliably identifies the underlying library and often the exact application.
Anti-bot systems use JA3 to distinguish real browsers from scrapers. Python's `requests` library, curl, and Scrapy each produce JA3 hashes that differ markedly from Chrome or Firefox. Even if a scraper sends identical HTTP headers, a mismatched JA3 is a high-confidence bot signal.
Countermeasures include using a browser-based HTTP client that inherits the browser's TLS stack (Playwright, Puppeteer), patching the TLS library to emit a Chrome-compatible ClientHello, or using a proxy that terminates and re-opens the TLS connection with the correct fingerprint.