<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>scrapfly.dev</title><link>https://scrapfly.dev/</link><description>Recent content on scrapfly.dev</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 12 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://scrapfly.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Your Browser Does Math Differently on Every OS, and Anti-Bot Systems Read the Bits</title><link>https://scrapfly.dev/posts/browser-math-os-fingerprint/</link><pubDate>Sun, 12 Jul 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/posts/browser-math-os-fingerprint/</guid><description>Math.tanh, every CSS trig function, and the Web Audio compressor all route through the host libm, so the rounding of a cosine betrays the OS a browser actually runs on. Where the leak lives across V8, Blink, and Web Audio, and what bit-for-bit reproduction of Apple&amp;rsquo;s math library takes to close it.</description></item><item><title>Your Browser's Hyphenation Dictionary Names the OS It Runs On</title><link>https://scrapfly.dev/posts/browser-hyphenation-os-fingerprint/</link><pubDate>Sun, 12 Jul 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/posts/browser-hyphenation-os-fingerprint/</guid><description>CSS hyphens:auto uses a per-language dictionary, and macOS and Windows/Linux Chrome ship disjoint dictionary sets from two different engines. Which languages a browser will hyphenate, and where it breaks them, classifies the OS with one DOM read. Why closing it for a macOS profile means reverse-engineering Apple&amp;rsquo;s CFBurstTrie format and reconstructing its hyphenation bit-for-bit.</description></item><item><title>The Math Behind the Audio Fingerprint</title><link>https://scrapfly.dev/posts/audio-fingerprint-math/</link><pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/posts/audio-fingerprint-math/</guid><description>The audio fingerprint stopped separating browsers and now separates CPUs: x86 and Apple Silicon build the oscillator wavetable with different FFTs. Why per-session noise cannot hide a 1-to-22-ULP gap, and what reproducing Apple&amp;rsquo;s vDSP FFT on x86 down to a double-precision base case actually involves.</description></item><item><title>About</title><link>https://scrapfly.dev/about/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/about/</guid><description>About scrapfly.dev, the engineering blog of Scrapfly.</description></item><item><title>WebAssembly Runs Identically Everywhere, Except Where It Leaks Your CPU</title><link>https://scrapfly.dev/posts/wasm-cpu-architecture-leak/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/posts/wasm-cpu-architecture-leak/</guid><description>WebAssembly is deterministic except for NaN bit patterns and relaxed SIMD, and both leak whether the CPU underneath is ARM or x86. How a browser claiming Apple Silicon on an x86 server gets caught by a 30-byte module, and how to emit ARM&amp;rsquo;s bits across every V8 compiler tier.</description></item><item><title>CDP over CBOR, msgpack and Snappy: three formats, one bug</title><link>https://scrapfly.dev/posts/cdp-cbor-msgpack-snappy/</link><pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate><guid>https://scrapfly.dev/posts/cdp-cbor-msgpack-snappy/</guid><description>How a single CDP message travels through three different serialization formats between Scrapium (our stealth-patched Chromium build) and our scraping infrastructure, what each format is doing for us, the UTF-8 vs UTF-16 trap that lives at the CBOR layer, and a production case our monitoring caught that taught us our two implementations did not agree on what a &amp;lsquo;string&amp;rsquo; was.</description></item></channel></rss>