fuzzing

2 posts

meta

Rust at Scale: An Added Layer of Security for WhatsApp (opens in new tab)

WhatsApp has deployed a Rust-based media security layer across billions of devices to defend against malware hidden in images, videos, PDFs, and other attachments. The system, called Kaleidoscope, validates file formats and identifies suspicious content before it reaches vulnerable downstream libraries. WhatsApp’s large-scale rollout demonstrates Rust’s production readiness and supports the company’s broader shift toward memory-safe languages. ## Media Handling as a Security Boundary - WhatsApp’s default end-to-end encryption protects messages, but shared media can still contain maliciously crafted files. - Attackers may exploit vulnerabilities in: - Operating system libraries - Media parsers - WhatsApp itself - Dangerous attachments can appear harmless, particularly when malware is concealed in images or videos. ## Lessons from the 2015 Stagefright Vulnerability - Android’s Stagefright vulnerability affected operating-system media-processing libraries. - Applications could not directly patch the vulnerable libraries, while users often took months to update their devices. - WhatsApp adapted its existing cross-platform C++ `wamedia` library to identify malformed MP4 files that could trigger vulnerable parsers. - This allowed WhatsApp to protect users faster than relying solely on operating-system updates. - Because the library automatically processes untrusted downloads, WhatsApp identified it as a strong candidate for memory-safe implementation. ## Replacing C++ with Rust - WhatsApp developed the Rust implementation alongside the original C++ version rather than performing a gradual rewrite. - Differential fuzzing, unit tests, and integration tests verified compatibility. - Key challenges included: - Increased binary size from the Rust standard library - Build-system support for WhatsApp’s many target platforms - The final implementation replaced approximately 160,000 lines of C++ with 90,000 lines of Rust, including tests. - Rust provided performance and runtime memory-use improvements. - The library was deployed across Android, iOS, Mac, Web, wearables, and other platforms. ## Kaleidoscope’s File Checks - Kaleidoscope expands beyond basic MP4 validation by checking for: - Non-conforming structures that could exploit parser differences - Embedded files and scripts in PDFs - Files that disguise their type through spoofed extensions or MIME types - Known dangerous formats such as executables and applications - These checks support safer handling in WhatsApp’s user interface and help defend against malicious attachments and unofficial clients. - The system cannot prevent every attack, but it adds an important defense-in-depth layer. ## WhatsApp’s Broader Security Strategy - WhatsApp distributes the libraries each month to billions of phones, computers, watches, and browsers across WhatsApp, Messenger, and Instagram. - The company describes this as the largest deployment of Rust code across diverse end-user platforms. - Its wider security program includes: - End-to-end encrypted messages, calls, and backups - Key transparency and additional calling protections - Fuzzing, static analysis, audits, and attack-surface monitoring - CVE reporting and an expanded bug bounty program - WhatsApp’s vulnerability strategy focuses on minimizing attack surface, strengthening remaining C and C++ code, and choosing memory-safe languages for new development. - Existing protections include control-flow integrity, hardened allocators, safer buffer APIs, specialized developer training, and automated analysis. WhatsApp plans to accelerate Rust adoption, particularly for security-sensitive, cross-platform components that process untrusted input. Its media library rollout provides evidence that Rust can deliver both memory safety and performance at global consumer scale.

figma

Debugging Data Corruption with Emscripten | Figma Blog (opens in new tab)

Figma encountered intermittent save-file corruption caused by an elusive C++ memory-safety bug. Conventional debugging tools failed because the web app’s asynchronous behavior made the problem nondeterministic. A keyboard-and-mouse fuzzer eventually produced reproducible failures, while understanding Emscripten’s C++-to-JavaScript memory model helped narrow the investigation. ## Detecting the Corruption - Invalid save files appeared occasionally and could not be reliably reproduced. - Figma’s files used ZIP containers around Google FlatBuffers documents. - The serialized bytes looked mostly valid, but some offsets were unexpectedly zeroed. - Data being written to the wrong location suggested a memory-safety violation such as: - Use before initialization - Use after free - Out-of-bounds access ## Why C++ Made the Bug Difficult - C++ was valuable for Figma because it provided: - Access to libraries such as FreeType, HarfBuzz, and Skia - Low-level control suitable for graphics software - Mature debugging and optimization tools - However, C++ offers no built-in protection against memory errors. - The team tried avoiding deallocation, enabling malloc diagnostics, fixing Valgrind and Clang Analyzer findings, and upgrading the compiler, but none exposed the corruption. ## Reproducing the Failure with Fuzzing - The team planned to eliminate nondeterminism by recording user events and replaying them deterministically. - Building a complete session recorder was too large a project, so they limited inputs to keyboard and mouse events. - A fuzzer generated random event sequences and ran them against the application. - After several days, it produced multiple save failures, providing reproducible cases for debugging. ## Emscripten’s Emulated Memory Model - Figma’s C++ editor ran in the browser through Emscripten, which compiled C++ into JavaScript. - JavaScript typed arrays and shared `ArrayBuffer` storage allowed Emscripten to emulate contiguous C++ memory. - In the generated code: - Pointer loads became typed-array reads. - Pointer stores became typed-array writes. - Registers became local variables. - Shared buffers enabled pointer reinterpretation between types. - Emscripten generated asm.js-style JavaScript, using type annotations and operations optimized for JavaScript JIT compilers. The combination of deterministic fuzzing and knowledge of Emscripten’s low-level memory representation provided the path toward isolating the corruption, even though the ultimate fix was reportedly only a three-line change.