docs/security/security-for-agents.md
This document describes the fundamental security architecture and assumptions of Chromium, which is called the "security model" of Chromium. It also describes common types of violations of that model, which are attacks against Chromium.
Some parts of this document make reference to V8 as well. V8 can be built as a standalone tool called "d8", which is useful for finding or demonstrating some kinds of attacks.
Notes for humans: this document is not part of the VRP rules or guidelines; it is advice for AI agents auditing Chromium for bugs.
Chromium is separated into several processes, including the browser process, the GPU process, the network service process, and potentially many renderer and utility processes. Each process except the browser process is inside a "sandbox", which uses primitives supplied by the OS to constrain what that process can do. The sandbox is different for each type of process. Renderer and utility processes have the strongest sandbox, the network and GPU processes have weaker sandboxes, and the browser process has no sandbox at all.
Communication between processes happens over an IPC system named Mojo. Mojo sends messages between processes, with serialization and deserialization at either end, and can also pass file handles and some other kinds of object between processes. Mojo allows for interprocess calls to methods grouped together into interfaces, and not all interfaces are available to all callers.
The fundamental unit of isolation on the web is the "origin". A "page" is the contents of a tab, which may be composed of content from multiple origins combined together. In general, scripts or other content from one origin shouldn't affect or see scripts or content from another origin, unless both origins opt into sharing.
Inside Chromium, a WebContents represents a single loaded page, and may contain content from multiple origins which are hosted in separate RenderFrames. RenderFrames that are in different origins are usually in separate renderer processes, isolated from each other.
When discussing attacks across origins, we sometimes use the example origins "evil.com" to mean an attacker's origin, and "good.com" to mean an origin they are trying to steal or corrupt data from. In this context, both origins are generally assumed to be loaded in Chromium at the same time, but in separate frames.
Chromium exposes several ways for websites to run their own code on the user's machine. The two most common are Javascript and Webassembly. V8 is responsible for handling both of these, and V8 should ensure that code supplied by websites isn't able to have dangerous effects inside the renderer process, like corrupting memory or causing a use-after-free of an object.
V8 compiles Javascript or Webassembly into native code to be executed by the CPU. V8 must guarantee that that native code it generates doesn't break certain safety properties, such as being unable to overwrite data structures that aren't meant to be exposed to Javascript.
There are a few different possible build configurations of Chromium or of V8. The three that are most relevant for security purposes are:
is_asan=false is_debug=false in args.gnis_asan=false is_debug=true in args.gnis_asan=true is_debug=false in args.gnThere are several different ways that invariants in Chromium and V8 are enforced. The CHECK macro enforces an invariant even in released builds, and the DCHECK macro enforces an invariant in debug builds only. Some kinds of invariant violation, like indexing outside the bounds of a base::span, are also detected in release builds and cause an immediate crash.
Every attack comes with a series of steps, which are generally supplied as a short program, called a "proof of concept". A "proof of concept" provides evidence that a bug is present, and is not the same thing as an "exploit", which makes use of a bug to achieve a malicious goal. A "proof of concept" is by definition harmless, but should have some objective and verifiable external effects to demonstrate that the bug is present.
A security bug report (or vulnerability report) is a description of how to execute an attack. Every security bug report must take the form: "An attacker can cause Chromium to [something which harms the user] by [attack steps]." For example:
window.foo(12345).foo().foo attribute set to bar.Unless you can clearly describe both the security harm to the user, and the attack steps, you do not have a security bug report.
A security bug that allows for execution of arbitrary code of an attacker's choice outside of any sandbox (so in the browser process or elsewhere in the OS outside of Chromium) or in a sandbox weaker than the renderer sandbox (some target process) is the most severe category of attack. These bugs generally take two forms:
For this kind of bug, the proof of concept must either:
To simulate a compromised renderer process, use the MojoJS feature by passing
--enable-features=MojoJS to Chromium. This allows you to call Mojo methods
from JavaScript. If that does not work for some reason, the proof of concept
may be in the form of a patch intended to apply to the Chromium source tree.
If so, this patch must modify code that is only executed in the renderer, to
simulate a compromised renderer process.
Anything that does not lead to one of these consequences is almost certainly not a valid proof of concept for an escalated code execution bug.
A security bug that allows for execution of arbitrary code of an attacker's choice inside the renderer sandbox is a renderer code execution bug. These bugs generally take two forms:
For V8, code compiled from attacker-supplied Javascript or Webassembly is executed inside a "heap sandbox", which confines memory reads and writes performed by that compiled code to a certain region. Bugs which allow for reading or writing memory outside the heap sandbox are "heap sandbox escapes" and are very valuable bugs. Bugs which allow for reading or writing memory inside the heap sandbox are less valuable but still valuable.
For this kind of bug, the proof of concept must either:
Not all DCHECK failures in V8 or d8 are security bugs, but many are, so to be conservative we assume that all of them are security bugs until we are confident they are not.
Any proof of concept that uses d8 must use --run-as-security-poc, in
addition to any other command-line arguments it needs. Proofs of concept that do
not work with --run-as-security-poc are not security bugs.
A security bug that allows for one origin to either read data from another origin or run code in another origin is a cross-site bug. There are some intentional ways to share data between origins, but by default origins shouldn't be able to interact.
A proof of concept of a cross-site bug must show that:
A bug which allows an extension to take actions it shouldn't be able to is an extension security bug. Extensions have permissions defined in their manifest.json, and all extensions have certain implicit permissions like the ability to make network requests in their own context.
For this kind of bug, the proof of concept is an extension which, when loaded, takes an action the extension should not be able to take.
Any other bug which allows a website to cause Chromium to harm a user may be a security bug, even if it doesn't fit one of these categories. Any such bug needs a clear explanation of the security consequences of the bug, as well as who can exploit it. Such a bug also needs clear reproduction steps or an executable proof of concept.
There are some common kinds of reports which are not security bugs in Chromium:
--single-processunsafe--run-as-security-poc added to
the command line.These are not security bugs, regardless of how easy they are to trigger. Under no circumstances is something matching an entry in this list a security bug.
When reporting a bug:
In general, a shorter bug report is better. Bug reports should be as short as possible, but no shorter.
The docs/security directory contains other security-related documentation. You should also consult the README.md and SECURITY.md files for the directories you are looking for bugs in, if they are present.