How Chromium Uses CORB to Defend Against Spectre Attacks

This article provides a comprehensive overview of how the Chromium web browser implements Cross-Origin Read Blocking (CORB) to mitigate Spectre side-channel attacks. By inspecting network traffic before it reaches the webpage's rendering process, Chromium prevents sensitive cross-origin data—such as JSON, XML, and HTML—from ever entering the memory space where a Spectre attack could read it. Below, we break down the threat model of Spectre in the browser, the multi-process architecture of Chromium, and the exact steps CORB takes to sniff, evaluate, and strip sensitive data from unauthorized cross-origin requests.

The Spectre Threat to Web Browsers

Traditionally, web browsers relied on the Same-Origin Policy (SOP) to keep websites isolated from one another. If evil.com requested a sensitive file from bank.com using an <img> or <script> tag, the browser would fetch the file, place it into the renderer process memory, and then rely on SOP to prevent evil.com from reading the file's contents.

The discovery of the Spectre CPU vulnerability broke this security model. Spectre allows malicious JavaScript to read arbitrary memory within the same operating system process. Consequently, if evil.com simply tricks the browser into loading bank.com data into the shared renderer process memory, the attacker can use a Spectre side-channel attack to read that data directly from memory, completely bypassing the Same-Origin Policy.

Enter Cross-Origin Read Blocking (CORB)

To defeat Spectre, Chromium introduced Site Isolation, which places different websites into separate operating system processes. However, an attacker can still request cross-origin subresources (via <img> or <script> tags) to pull foreign data into their own renderer process.

Cross-Origin Read Blocking (CORB) is the defense mechanism designed to stop this. CORB prevents the browser from delivering sensitive cross-origin network responses to a renderer process unless the server explicitly permits it.

How Chromium Implements CORB

Chromium utilizes a multi-process architecture that separates the Network Process (which handles fetching data from the internet) from the Renderer Process (which executes JavaScript and renders the webpage). CORB operates entirely within the privileged Network Process, acting as a gatekeeper before data is passed to the untrusted Renderer Process.

Here is the step-by-step implementation of how CORB processes a cross-origin request:

1. Identifying Protected Data Types

CORB does not block all cross-origin traffic, because the web relies on loading cross-origin images, stylesheets, and scripts. Instead, CORB specifically targets data formats that contain sensitive information and have no business being loaded into tags like <img> or <script>. These protected MIME types are:

  • text/html
  • application/xml (and text/xml, application/xhtml+xml, etc.)
  • application/json (and text/json)

If a cross-origin response declares one of these MIME types, CORB flags it for further inspection.

2. Checking for CORS Exceptions

Before blocking a flagged resource, CORB checks if the cross-origin request is actually legitimate. If the request was made using Cross-Origin Resource Sharing (CORS)—for example, via a fetch() or XMLHttpRequest call—and the response includes valid Access-Control-Allow-Origin headers permitting the requesting origin, CORB allows the data to pass through to the renderer process.

3. Checking the nosniff Header

If the request is not permitted by CORS, CORB checks if the server included the X-Content-Type-Options: nosniff HTTP header. If this header is present alongside a protected MIME type (HTML, XML, or JSON), CORB immediately blocks the response without inspecting the payload.

4. Content Sniffing

Web servers are frequently misconfigured. Sometimes a server will label an image or a JavaScript file with a text/html MIME type. If CORB blindly blocked everything labeled text/html, it would break legitimate websites.

To prevent breaking the web, if the nosniff header is absent, Chromium's Network Process performs "content sniffing." It reads the first 1,024 bytes of the response body to verify if the content actually matches the declared MIME type:

  • For HTML: It looks for valid HTML tags (like <!DOCTYPE html>, <html>, <head>, <script>, <iframe>).
  • For XML: It looks for the <?xml declaration.
  • For JSON: It looks for valid JSON syntax (such as starting with { or [ followed by a quotation mark) or a known JSON security prefix (often called a parser-breaker, like )]}').

If the sniffing confirms the file is genuinely HTML, XML, or JSON, CORB decides to block it. If the sniffing fails (meaning the file is likely a mislabeled image or script), CORB allows the file through to avoid breaking the webpage.

5. Stripping the Response (Sanitization)

When CORB decides to block a response, it does not simply cancel the network request, as doing so could leak information to the attacker about the existence of the file.

Instead, the Network Process sanitizes the response. It replaces the entire response body with an empty byte stream and strips away all HTTP headers (except for safe CORS-related headers). This empty, harmless response is then sent to the Renderer Process.

By stripping the data in the Network Process, the sensitive bytes never enter the memory space of the Renderer Process. Even if a malicious script successfully executes a Spectre attack within the renderer, the sensitive cross-origin data is simply not there to be stolen.