The web platform offers a number of tools to web developers which enable mitigation of a few important threats. In order to understand how these are being used in the wild, and evaluate our success at promulgating them, we collect some usage statistics; this document outlines those counters and points to some helpful graphs.
We believe that a carefully-crafted Content Security Policy can help protect web applications from injection attacks that would otherwise lead to script execution. Strict CSP is a reasonable approach, one which we'd like to encourage.
In order to understand CSP‘s use in the wild, we can look at a few counters that give some insight into the percentage of Chrome users’ page views that use CSP in a given way:
kContentSecurityPolicy
(graph) tracks the overall usage of Content-Security-Policy
headers. Likewise, kContentSecurityPolicyReportOnly
(graph) tracks the report-only variant.To get a feel for the general quality of policies in the wild, we want to evaluate how closely developers are hewing to the strictures of Strict CSP. We've boiled that down to three categories:
Does the policy reasonably restrict object-src
? The only “reasonable” restriction, unfortunately, is object-src 'none'
. kCSPWithReasonableObjectRestrictions
and kCSPROWithReasonableObjectRestrictions
track that directive value in enforced and report-only modes respectively.
Does the policy reasonably restrict base-uri
in order to avoid malicious redirection of relative URLs? base-uri 'none'
and base-uri 'self'
are both appropriate, and are tracked via kCSPWithReasonableBaseRestrictions
and kCSPROWithReasonableBaseRestrictions
in enforced and report-only modes respectively.
Does the policy avoid using a list of hosts or schemes (which research has shown to be mostly ineffective at mitigating attack)? kCSPWithReasonableScriptRestrictions
and kCSPROWithReasonableScriptRestrictions
track the policies whose script-src
directives rely upon cryptographic nonces and/or hashes rather than lists of trusted servers, and which also avoid relying upon 'unsafe-inline'
.
Policies that sufficiently restrict all of the directives above (object-src
, base-uri
, and script-src
) are tracked via kCSPWithReasonableRestrictions
and kCSPROWithReasonableRestrictions
. This is the baseline we'd like pages generally to meet, and a number we hope we can drive up over time.
We're also tracking a higher bar, which includes all the restrictions above, but also avoids relying upon 'strict-dynamic'
, via kCSPWithBetterThanReasonableRestrictions
and kCSPROWithBetterThanReasonableRestrictions
.
kIFrameCSPAttribute
records the overall usage of the csp
attribute on <iframe>
elements, which enables pages to enforce a policy on documents they embed.
Trusted Types gives page authors a means to protect their sites against cross-site scripting attacks. In order to understand real-world Trusted Types usage we obtain the following usage counts:
General use:kTrustedTypesEnabled
, kTrustedTypesEnabledEnforcing
, and kTrustedTypesEnabledReportOnly
. The first tells us (relative to all page loads) how many pages have any form of Trusted Types enabled, while the other two allow us to determine which percentage of pages run in enforcing or report-only mode (or both).
Tracking specific features: kTrustedTypesPolicyCreated
tracks creation of all Trusted Types policies, kTrustedTypesDefaultPolicyCreated
notes whether a “default” policy has been created. kTrustedTypesAllowDuplicates
records whether an ‘allow-duplicates’ keyword has been used.
Error tracking: kTrustedTypesAssignmentError
tracks whether Trusted Types has blocked a string assignment.
Cross Origin Isolation policies refer to a number of header based policies that developers can send to enforce specific rules about how their content can be embedded, opened from, etc. It is also used to gate certain APIs that would be otherwise too powerful to use in a post-Spectre world.
Cross-Origin-Resource-Policy restricts a resource to only be fetched by “same-origin” or “same-site” pages.
“NetworkService.CrossOriginResourcePolicy.Result” UMA histogram records the result of the CORP check.
“NetworkService.CrossOriginResourcePolciy.ReportOnlyResult” UMA histogram records the result of the CORP check, only when a Cross-Origin-Embedder-Policy-Report-Only header is attached to the initiator context. The format is same as “NetworkService.CrossOriginResourcePolicy.Result”.
Cross-Origin-Opener-Policy is used to restrict the usage of window openers. Pages can choose to restrict this relation to same-origin pages with similar COOP value, same-origin unless they are opening popups or put no restriction by default.
Usage of COOP is tracked via:
kCrossOriginOpenerPolicySameOrigin
kCrossOriginOpenerPolicySameOriginAllowPopups
kCoopAndCoepIsolated
They correspond respectively to the values: “same-origin”, “same-origin-allow-popups” and “same-origin” used conjointly with COEP.Usage of COOP in report-only mode is tracked symmetrically via:
kCrossOriginOpenerPolicySameOriginReportOnly
kCrossOriginOpenerPolicySameOriginAllowPopupsReportOnly
kCoopAndCoepIsolatedReportOnly
We track how often same-origin documents are present in two pages with different COOP values via kSameOriginDocumentsWithDifferentCOOPStatus
. We might restrict synchronous access between those in order to allow COOP “same-origin-allow-popups” to enable crossOriginIsolated when used in conjunction with COEP.
Cross-Origin-Embedder-Policy is used to restrict the embedding of subresources to only those that have explicitly opted in via [Cross-Origin-Resource-Policy].
Usage of COEP is tracked via:
kCrossOriginEmbedderPolicyCredentialless
kCrossOriginEmbedderPolicyRequireCorp
.Usage of COEP in report-only mode is tracked symmetrically via:
kCrossOriginEmbedderPolicyCredentiallessReportOnly
kCrossOriginEmbedderPolicyRequireCorpReportOnly
.Usage of COEP in SharedWorker is tracked via:
kCoepNoneSharedWorker
,kCoepRequireCorpSharedWorker
kCoepCredentiallessSharedWorker
.Note that some APIs having precise timers or memory measurement are enabled only for pages that set COOP to “same-origin” and COEP to “require-corp”.
kCoopAndCoepIsolated
.The Sanitizer API provides a browser-maintained “ever-green”, safe, and easy-to-use library for user input sanitization as part of the general web platform.
kSanitizerAPICreated
and kSanitizerAPIDefaultConfiguration
tell us how many Sanitizers are created and how many Sanitizers are created without custom configurations.kSanitizerAPIToFragment
, kSanitizerAPISanitizeFor
, and kSanitizerAPIElementSetSanitized
measure which API entry point has been called.kSanitizerAPIActionTaken
shows how many times a sanitize action has been performed while calling the Sanitizer APIs. (That is, on how many sanitizer calls did the sanitizer remove nodes from the input sets.)kSanitizerAPIFromString
, kSanitizerAPIFromDocument
and kSanitizerAPIFromFragment
tell us what kind of input people are using.Private Network Access helps to prevent the user agent from inadvertently enabling attacks on devices running on a user‘s local intranet, or services running on the user’s machine directly.
Use of PNA in workers tracked via:
kPrivateNetworkAccessFetchesWorkerScript
kPrivateNetworkAccessWithWorker
kPrivateNetworkAccessNullIpAddress
is an experimental use counter for accesses to the 0.0.0.0 IP address (and the corresponding [::]
IPv6 address). These can be used to access localhost on MacOS and Linux and bypass Private Network Access checks. We intent to block all such requests. See https://crbug.com/1300021 and https://github.com/whatwg/fetch/issues/1117.