blob: 3a09304a1360e92f7db63409049a548a11c3a164 [file] [view]
# Connection Allowlist Design
References:
* [Explainer][1]
* [Spec][2]
* [Chrome Status Entry][3]
* [Design Document][4]
## Summary
Connection Allowlist restricts network connections in Chromium using a
URLPattern allowlist returned by the server. The high-level flow is:
* The allowlist is returned in the HTTP response when loading a given
context (document or worker)
* A `network_restrictions_id` is assigned to that context, which is used to
identify requests that originate from it
* Enforcement then focuses on blocking requests containing that ID based on
the mapped allowlist.
This document outlines the architectural design and the checks performed
across different Chromium layers (network service, browser, renderer).
All security and resource restrictions (CSP, Connection Allowlists, etc.) are
applied **restrictively and additively**. A request must satisfy **all**
applicable security policies to proceed; if any policy blocks the request, the
request is blocked.
## Design
### Network service integration
The network service is the primary layer where network requests are handled and
dispatched. The majority of Connection Allowlist enforcement occurs here.
* **Responsibilities:**
* Intercept and filter outgoing network requests.
* Apply allowlist rules at the URLLoader level (including document-initiated
prefetches which are associated with the document's
`network_restrictions_id`).
* Enforce allowlists for other networking APIs like WebSockets, DNS Prefetch,
and WebTransport.
* **Benefits:**
* **Defense-in-Depth:** Since enforcement occurs in the Network Service
process, compromised renderer processes cannot bypass these checks.
* **Centralized Enforcement:** The Network Service handles HTTP/HTTPS
requests, WebSockets, and WebTransport. Enforcing allowlists at this level
provides a single, uniform point of control across different network
protocols.
* **Semantic Consistency:** Once registered, allowlist matching happens
within the Network Service process. This ensures that the same set of
rules is applied to all requests regardless of where they originated
(e.g. fetch, fetch redirects, prefetch, worker, etc.).
* **Extensibility:** The token-based mapping (`network_restrictions_id`) is
highly extensible. Other future security features or JS-based network
restriction APIs (similar to the dynamic
`window.fence.disableUntrustedNetwork()` design previously used for Fenced
Frames, see [CL 7709872][5]) can leverage this same plumbing to dynamically
register and enforce rules in the Network Service.
#### Network restrictions ID (`network_restrictions_id`)
To map network requests back to the corresponding context (document or worker)
and its connection allowlists, each context is associated with a unique token,
the `network_restrictions_id` (a `base::UnguessableToken`).
* **Creation & Propagation**:
* During cross-document navigation, a new `network_restrictions_id` is
created on the `NavigationRequest` in
`NetworkRestrictionsNavigationThrottle`.
* Upon navigation commit, this ID is wrapped in a ref-counted handle
(`base::RefCountedData<base::UnguessableToken>`) and stored in the
document's `DocumentAssociatedData` (or worker hosts like
`DedicatedWorkerHost` and `SharedWorkerHost`).
* Ref-counting is used because there are edge cases where multiple documents
can share the same `network_restrictions_id` (e.g., initial empty documents
inheriting their creator's ID).
* **Updating the Network Service**:
* If a document has active connection allowlists (enforced or report-only)
determined from policy container policies, the browser process registers
them via `StoragePartitionImpl::RestrictNetworkForIdsInNetworkContext`.
* This sends the ID and allowlisted patterns to the `NetworkContext` in the
Network Service using `RestrictNetworkForIds()`.
* The navigation is deferred during the throttle check
(`WillProcessResponse` / `WillCommitWithoutUrlLoader`) until the Network
Service confirms the restrictions have been registered, ensuring
restrictions are applied before resource loading begins.
* **Backup & Recovery**:
* `StoragePartitionImpl` stores a copy of the restrictions in
`network_restrictions_ids_`. In case of a Network Service crash, this map
is used to restore the network restrictions on the new `NetworkContext`.
* **Lifetime & Cleanup**:
* When a document's `DocumentAssociatedData` or worker is destroyed, if it
holds the last reference to the ref-counted `network_restrictions_id`, it
schedules a cleanup of the restriction mapping from the Network Service
and `StoragePartitionImpl` using
`StoragePartitionImpl::ClearNetworkRestrictionsAfterDelay`.
* **Selecting the ID at Calling Sites**:
When a calling site initiates a request or creates a connection (e.g.
WebSocket, WebTransport) that expects a `network_restrictions_id`, it
should use:
* **The context's ID**: If the request/connection is associated with a
specific context (document, dedicated worker, shared worker, or service
worker), use that context's `network_restrictions_id`.
* **`network::GetNoOpNetworkRestrictionsId()`**: When no network
restrictions should be applied, bypassing restrictions entirely. This
should be used carefully as it bypasses the Connection Allowlist (e.g.,
for browser-initiated requests that do not have an associated
frame/context).
* **`network::GetTestNetworkRestrictionsId()`**: In tests that require a
valid network restrictions ID but do not test Connection Allowlist
behavior.
### Browser process checks (content/browser)
The browser process coordinates navigation checks and handles security
policies.
* **Responsibilities:**
* Store and manage Connection Allowlists as part of the `PolicyContainerHost`
associated with each document.
* Intercept and validate navigations in the browser process before they are
sent to the network service using the
`NavigationRequest::IsAllowedByConnectionAllowlist` function. This function
enforces allowlist policies during key phases of navigation (such as
initial request start and handling redirects).
### Blink checks
Blink is the rendering engine running in the renderer process.
* **Responsibilities:**
* Enforce Connection Allowlists in the renderer process for:
1. WebRTC connections. These checks are also validated in the network
service to handle compromised renderers.
2. Requests initiated via `fetch()` when they will be intercepted by a
Service Worker. This is done in blink because the renderer directly
talks to the Service Worker URLLoaderFactory in these cases, not giving
the document's URLLoaderFactory checks a chance to run, unless the SW
decides to fallback on the original fetch. This applies when the
initiating context is either a document, dedicated worker or shared
worker.
### Integration with service workers
Service Workers act as network proxies in the renderer process, intercepting
requests before they reach the network.
* **Responsibilities:**
* **Main Script Fetches & Update Checks**: Subject Service Worker main script
fetches and update checks to the Connection Allowlists of the
**creator/initiator context**(the registering document).
* **Initial Install**: The browser process creates the loader factory via
`GetLoaderFactoryForMainScriptFetch` passing the
`creator_network_restrictions_id_`.
* **Update Checks**: During soft update checks (in
`ServiceWorkerRegisterJob::UpdateAndContinue`), the loader factory is
created via `GetLoaderFactoryForUpdateCheck` passing the
`creator_network_restrictions_id_`.
* **Intercepted Document Fetches**: Ensure requests initiated by a document
that are intercepted by a Service Worker are validated in Blink against the
**document's** Connection Allowlists before they are forwarded to the
Service Worker. This prevents documents from bypassing their own
restrictions, including when the Service Worker attempts to serve
responses from Cache Storage.
* **Service Worker Outgoing Fetches**: Apply the Service Worker's own
Connection Allowlists (persisted and restored via the database) to its
own fetches.
* Requests initiated directly by the Service Worker context
(`ServiceWorkerGlobalScope`) itself (via `fetch()`) are governed by the
policies stored in its own `PolicyContainerHost`. Those are mapped to
the Service Worker's own `network_restrictions_id` in the Network
Service via the `NetworkRestrictionsWorkerThrottle`. This throttle also
does the same for dedicated and shared worker contexts.
* Once a request is inside the Service Worker, any outgoing network
fetches (e.g., via `event.respondWith(fetch(request))`) are initiated
using the Service Worker's `URLLoaderFactory` and subjected to the
**Service Worker's** Connection Allowlists (associated with the Service
Worker's own `network_restrictions_id`), regardless of the client
document's policies. Consequently, redirects of these fetches are
checked against the Service Worker's connection allowlist's redirect
flag, not the document's.
* **Navigation Preload**: Navigation preload requests are subject to the
**Service Worker's** Connection-Allowlist. If the navigation itself is
allowed by the document's Connection-Allowlist, the associated navigation
preload request will be executed using the Service Worker's
`URLLoaderFactory` (which is associated with the Service Worker's
`network_restrictions_id`), thereby enforcing the Service Worker's
policies.
* **clients.navigate() in Service Workers**: Navigation initiated via
clients.navigate() is subject to both the Service Worker's and the
document's Connection Allowlists. Since the navigation is initiated from
the Service Worker context, the Service Worker's Connection Allowlists
apply to the navigation before it is initiated from the Service Worker.
In addition, since the navigation is on a window client (which has an
associated Document), the Document's Connection Allowlists also apply,
and if there is a server redirect, the document's Connection Allowlists'
redirect bit will be checked.
* **clients.openWindow() in Service Workers**: Navigation initiated via
clients.openWindow() is subject to the Service Worker's Connection
Allowlists before it is initiated. There is no check on redirect since
there is no CA to be checked once the navigation has started.
[1]: https://github.com/WICG/connection-allowlists
[2]: https://wicg.github.io/connection-allowlists/
[3]: https://chromestatus.com/feature/5175745573945344
[4]: https://docs.google.com/document/d/1B3LERUObjVDAKBNLpdIxbk8LC96rWUn1q8vtP9pPIuA/edit?usp=sharing
[5]: https://chromium-review.googlesource.com/c/chromium/src/+/7709872