SECURITY.md GuidelinesThis document explains how to write an effective SECURITY.md for components in Chromium. A SECURITY.md lives in your component's directory and documents its security boundaries, process model, threat assumptions, and explicit non-bugs for reviewers, maintainers, security researchers, and AI tools.
SECURITY.md in Chromium?A SECURITY.md establishes a clear security contract for your component. Without one, security researchers and automated scanning tools may file bugs on intentional design decisions, safe-context crashes, or intended error recovery, wasting your team's engineering time on triage.
A well-crafted Chromium SECURITY.md answers four basic questions:
1. Where does the code run (process type, sandbox level, privilege tier)?
2. What inputs are trusted vs. untrusted (and does it defend against a compromised renderer)?
3. Which vulnerability classes and behaviors are in scope vs. explicit non-bugs?
4. Why were specific design trade-offs made, and what risks are accepted?
Check off these items before committing your SECURITY.md:
Chromium's multi-process security model and bug taxonomy are canonically defined in central documentation:
When authoring a component SECURITY.md, you do not need to re-explain Chromium's global security model. Instead, specify how your component integrates with these architectural boundaries:
Identify the execution context of your component:
Browser Process: Unsandboxed, highest privilege. Has direct access to the filesystem, network, and profile data. All IPC endpoints must treat inputs from other processes as untrusted.
Renderer Process: Strongly sandboxed, lowest privilege. Runs untrusted web code (HTML/JS/Wasm/DOM). Other processes should assume that the renderer is compromised by attackers.
Utility Process: Sandboxed (sandbox strength can be stronger than the renderer's but that depends on utility sandbox type and whether code is reachable from web content). Used for decoding, parsing, or unpacking untrusted data.
Network Service (only on macOS) / GPU Process: Specialized sandboxed processes handling GPU commands and network I/O.
Note: The sandbox varies based on the OS. Android in particular has weak sandboxing so Android GPU bugs are always Sev-0.
Vulnerabilities that rely on a malicious web page compromising its own renderer process are valid as is the bug that allowed the renderer to be compromised.
Chromium permits at most two of these dangerous properties in the same process:
1. Untrustworthy input (web content, network data)
2. Complex processing (parsing, decompression, compilation)
3. Memory-unsafe language (C/C++)
If all three are combined, the code must run in a sandboxed process.
Note: Do not prompt agents to audit Rule of Two compliance directly, as valid browser C++ will trigger false positives.
Below is the recommended structure for a Chromium SECURITY.md file.
Define exact source tree paths and explicit exclusions.
## Scope This policy applies to code located in `//chrome/browser/my_component/` and subdirectories. It does not apply to `//chrome/browser/my_component/testing/` or mock utilities.
Define execution context, input hostility, and trust assumptions.
## Security Boundaries & Threat Model ### Process type & Sandbox Runs in the sandboxed Renderer process (or: sandboxed Utility process, un-sandboxed Browser process). ### Inputs - Untrusted: JavaScript parameters and DOM data passed from web content. - Trusted: Mojo IPC responses received from the Browser process. ### Trust relationships & Renderer Compromise - Defends against a compromised Renderer: Yes / No. - Trusts the Browser process. Does not trust peer Renderer processes.
Vulnerabilities that are globally in scope across Chromium, do not need to be restated in the SECURITY.md files as doing so risks accidental negative-implication by scanners or researchers. The security boundaries section should focus on component-specific boundaries based on common false-positive patterns such as:
Note: AI security scanners rely heavily on this section, so making sure that it's clear can reduce the number of and improve the quality of bugs that your engineers will need to triage.
## Security Boundaries & Explicit Non-bugs ### Security Boundaries - Enforces origin checks on privileged actions requested by Mojo IPC. - Sanitizes untrusted data before allowing other components to access it. ### Out of scope (non-bugs) - Crashes in safe sandboxed contexts: CHECK failures or null-pointer dereferences in the sandboxed Utility process that terminate safely without memory corruption. - Intra-process state: Bypassing local in-memory cache limits from within the same renderer process. - Internal API preconditions: Calling FooService methods directly with invalid pointers via unit tests or internal C++ calls without a reachable IPC path.
Document deliberate architectural trade-offs made for performance or memory efficiency.
## Design Justifications & Accepted Risks ### Shared memory IPC Uses shared memory for high-throughput video frame transfers. Mitigated by validating all header metadata and buffer sizes before reading. ### Accepted risk: network timing Network setup timing side channels are accepted residual risks.
Link to deeper design documents or architecture diagrams.
## Further Documentation - [Component Design Doc](path-to/my-component-design): Architecture overview. - [Mojo Interface Specification](path-to/my-component-mojo): IPC definitions and security considerations.
# Security Model for [Browser Service Name] ## Scope This policy applies to code in `//chrome/browser/my_service/` and subdirectories. ## Security Boundaries & Threat Model ### Process Type & Sandbox Runs in the un-sandboxed Browser process. Has full system access and profile data capability. ### Inputs - Untrusted / Semi-trusted: Mojo IPC messages received from sandboxed Renderer processes (`//third_party/blink/`). Renderers may be compromised. - Trusted: OS signals and internal local configuration. ### Mojo IPC Validation Must validate all Mojo arguments and verify calling process origin via ChildProcessSecurityPolicy. Out-of-bounds arguments or invalid origins must trigger mojo::ReportBadMessage(). ## In-Scope vs. Out-of-Scope ### In scope - Failure to validate origin or process permissions on incoming Mojo messages. - Memory corruption or logic bypasses in the Browser process triggered by IPC messages. ### Out of scope (non-bugs) - Expected feature disablement: Inability to access protected resources when user permission is denied.
Consult these canonical policy guides when defining your component's security contract:
| Category | Policy / Guide | Best Used For |
|---|---|---|
| Core Rules | Chrome Security Rules | All Chromium components |
| Core Rules | Chrome Security FAQ | All Chromium components |
| Core Rules | Security for Agents | AI-agent scannability |
| Core Rules | Severity Guidelines | Bug classification |
| Mojo & Web | Mojo IPC Security | Mojo interface safety |
| Mojo & Web | Web Platform | Web-facing APIs |
Consult live SECURITY.md files and reference documentation in the Chromium repository for gold-standard patterns: