Back to Articles

Rowhammer.js: Exploiting Hardware Vulnerabilities Through Your Browser

[ View on GitHub ]

Rowhammer.js: Exploiting Hardware Vulnerabilities Through Your Browser

Hook

What if visiting a malicious website could flip bits in your computer’s RAM, potentially escalating privileges or corrupting data—all without installing anything?

Context

The rowhammer problem is a hardware vulnerability in DRAM chips discovered around 2014. When you repeatedly access (‘hammer’) a row of memory cells, electrical interference can cause bit flips in adjacent rows—corrupting data you shouldn’t have access to. This breaks the fundamental security assumption that processes can’t interfere with each other’s memory. Initially, rowhammer exploitation required native code with direct memory access, limiting its reach to local attackers who could execute binaries. Researchers at ISEC, TU Graz asked a more disturbing question: could this hardware vulnerability be triggered remotely through JavaScript running in a web browser? The answer was yes, and Rowhammer.js was born. This proof-of-concept demonstrates that hardware-level attacks aren’t confined to system programming languages—high-level browser code can reach down and manipulate physical memory if you understand the underlying architecture deeply enough. The implications are significant: any website you visit could potentially attempt a rowhammer attack, turning a hardware manufacturing defect into a remote exploitation vector.

Technical Insight

Hardware Target

Browser Attack

Native Analysis

Physical addresses with bit flips

Maps to JS array indices

Allocates large typed arrays

Contiguous memory blocks

Evict sets bypass L3 cache

Bit flips in adjacent rows

Native C++ Rowhammer Tool

watch_firefox Mapper

JavaScript Rowhammer Code

Browser Memory Allocator

Cache Eviction Engine

DRAM Rows

Rowhammer Exploit

System architecture — auto-generated

Rowhammer.js bridges the enormous gap between JavaScript’s sandboxed execution environment and direct DRAM manipulation through sophisticated cache eviction strategies. The attack relies on a fundamental insight: to flip bits in DRAM, you need to bypass CPU caches entirely and trigger actual DRAM refresh cycles. JavaScript can’t directly control cache behavior, but the researchers developed techniques to exploit cache architecture.

The project provides a hybrid toolchain. First, you run native C++ tools to discover vulnerable memory addresses on your specific hardware. The ‘double_sided_rowhammer_haswell’ (or ‘double_sided_rowhammer_ivy’) binary performs traditional rowhammer attacks to find reproducible bit flips, outputting physical addresses where hammering adjacent rows causes corruption. You run this with a parameter specifying the number of DIMMs: ’./double_sided_rowhammer_haswell -d 1’. This step is crucial because rowhammer susceptibility varies dramatically between DRAM modules—you need to find your hardware’s weak spots. The program outputs information marked with ‘Print this for the watch_firefox tool’.

Once you have vulnerable addresses, the ‘watch_firefox’ tool maps these physical addresses to JavaScript array indices. You edit ‘watch_firefox.cc’ to contain the addresses from your native test, then run it while Firefox loads ‘rowhammer.html’. The tool monitors Firefox’s memory allocations, waiting for large contiguous blocks. When JavaScript allocates a typed array (by clicking the ‘Allocate’ button), the tool correlates addresses and calculates which array indices map to your target physical memory. The README notes ‘This is not yet automated’ and requires manually entering the virtual address of the array start when prompted. The program then prints the array indices to use in JavaScript, which you copy into the editbox and click ‘Parse’, after which you can start hammering.

The pure JavaScript variant in ‘rowhammer_scan.html’ eliminates native tools by making specific assumptions about memory layout. It assumes single-channel memory mode (one DIMM) and that the OS allocates physically contiguous memory in blocks of 2 megabytes—described as ‘the case if your OS allocates 2M anonymous pages (all our Linux systems do) or if it allocates physically contiguous 4K pages’. The scanner allocates a massive typed array by clicking ‘Allocate’, waits a second for Firefox to allocate memory, then systematically tests different index pairs to find hammerable rows when you click ‘Hammer’.

The cache eviction strategy is CPU-specific. The README explicitly states this version is ‘for Haswell CPUs with a 16-way L3 cache and no L4 cache’ and ‘will probably not work on other CPUs without modifications’. For Haswell’s 16-way set-associative L3 cache, the eviction patterns must be precisely calibrated to the cache geometry. This is why the tool is so architecture-dependent—cache geometry varies between CPU generations.

Both the ‘rowhammer.html’ and ‘rowhammer_scan.html’ versions support a ‘Refresh’ button that reloads only the JavaScript file (rowhammer.js or rowhammer_scan.js) while keeping the array and array indices in memory, allowing experimentation with different settings without reallocating memory or searching for indices again.

The JavaScript-only variant attempts to eliminate manual steps but sacrifices reliability. Without kernel-level address information, it makes educated guesses about memory layout based on Linux’s page allocation patterns. The researchers note that adaptive eviction strategy discovery ‘is very slow’ and ‘takes hours’, stating ‘there is not much use in doing this search in JavaScript’. They suggest ‘a more realistic adaptive approach would be to try different strategies that are already known to work on some CPUs’ rather than executing the generic eviction strategy finding algorithm. For those who want to try, the ‘cached’ function is already implemented in ‘rowhammer_scan.js’.

Gotcha

This is highly specialized research code with severe practical limitations. It targets only specific CPU architectures—the README explicitly states the JavaScript versions are ‘for Haswell CPUs with a 16-way L3 cache and no L4 cache’ and ‘will probably not work on other CPUs without modifications’. The native tools include separate binaries for Ivy Bridge and Haswell processors. Other Intel generations, AMD processors, or ARM chips would require completely different eviction strategies and cache geometry calculations. You can’t just run this on arbitrary hardware and expect results.

The manual calibration process is tedious and error-prone. You need to run native tools (the double_sided_rowhammer binaries) to find bit flips, which may take significant time. Then you must manually edit ‘watch_firefox.cc’ with the discovered addresses, run the tool while loading the browser page, wait for memory allocation, manually enter the virtual address when prompted (as ‘this is not yet automated’), and copy-paste the resulting indices into the HTML interface. The pure JavaScript version (‘rowhammer_scan.html’) eliminates some manual steps but only works under specific conditions: single-channel memory mode (one DIMM) and specific OS memory allocation patterns.

The researchers provide explicit warnings about danger: ‘This code may cause unexpected and undesirable behavior to occur on your machine. This code may not detect the vulnerability on your machine.’ They emphasize ‘Be careful not to run this test on machines that contain important data’ because ‘this test could cause bit flips that crash the machine, or worse, cause bit flips in data that gets written back to disc.’ They warn that on susceptible machines, ‘one process can corrupt pages used by other processes or by the kernel’ and advise that ‘if your computer is susceptible to the rowhammer bug, disable JavaScript in your browser! Attackers could exploit this bug through JavaScript and take control over your machine.’

Modern systems likely have mitigations. While the README doesn’t detail current countermeasures, it acknowledges that the JavaScript-only version ‘is not adaptive to all CPUs’ and that the eviction strategy finding algorithm performance issues mean ‘we will evaluate its performance’. The code appears to be from the original research period and may not reflect current browser security measures or hardware protections.

This is a footgun for understanding vulnerabilities, not a reliable exploit tool. The researchers state clearly that this is research code demonstrating proof-of-concept, adapted from Google’s rowhammer-test repository, and tied to their academic paper on remote software-induced fault attacks.

Verdict

Use if: You’re a security researcher studying hardware vulnerabilities and need to understand how high-level languages can exploit low-level bugs, you’re testing specific legacy systems (particularly Haswell or Ivy Bridge CPUs) for rowhammer susceptibility with appropriate precautions, or you’re building browser security mitigations and need a reference attack implementation. This is valuable academic code for understanding the intersection of hardware vulnerabilities and web security, as documented in the researchers’ paper ‘Rowhammer.js: A Remote Software-Induced Fault Attack in JavaScript’.

Skip if: You need a production-ready exploitation tool (this is research code requiring manual calibration), you’re working with CPU architectures other than the specifically supported Haswell and Ivy Bridge processors (it requires modifications for other systems), you lack the technical background to modify cache eviction strategies for your CPU architecture (it requires deep systems knowledge), or you’re looking for general-purpose security testing (use the original Google rowhammer-test repository instead). The researchers explicitly warn against running this on machines with important data due to risks of crashes and data corruption. Most developers should read the associated academic paper to understand the threat model but not actually run this code unless they have a specific research need, appropriate test hardware, and understand the serious risks involved.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/isec-tugraz-rowhammerjs.svg)](https://starlog.is/api/badge-click/developer-tools/isec-tugraz-rowhammerjs)