Bug 1942622 - Collect telemetry for all internal chrome: CSP violations. r=freddyb
Differential Revision: https://phabricator.services.mozilla.com/D235656
This commit is contained in:
@@ -51,3 +51,5 @@ run-if = ["os == 'win'"]
|
||||
|
||||
["browser_csp_blocks_event_handlers.js"]
|
||||
run-if = ["debug", "early_beta_or_earlier"]
|
||||
|
||||
["browser_csp_violation_telemetry.js"]
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_internal_page_telemetry() {
|
||||
Services.fog.testResetFOG();
|
||||
|
||||
is(
|
||||
Glean.security.cspViolationInternalPage.testGetValue(),
|
||||
null,
|
||||
`No telemetry should have been recorded yet for cspViolationInternalPage`
|
||||
);
|
||||
|
||||
// This page's CSP should disallow inline event handlers.
|
||||
const ROBOTS_URL = "chrome://browser/content/aboutRobots.xhtml";
|
||||
await BrowserTestUtils.withNewTab(ROBOTS_URL, async browser => {
|
||||
browser.contentDocument.documentElement.setAttribute("onclick", "foobar()");
|
||||
await BrowserTestUtils.waitForEvent(
|
||||
browser.contentDocument,
|
||||
"securitypolicyviolation"
|
||||
);
|
||||
});
|
||||
|
||||
let testValue = Glean.security.cspViolationInternalPage.testGetValue();
|
||||
is(testValue.length, 1, "Should have telemetry for one violation");
|
||||
let extra = testValue[0].extra;
|
||||
is(extra.directive, "script-src-attr", "violation's `directive` is correct");
|
||||
is(extra.selftype, "chromeuri", "violation's `selftype` is correct");
|
||||
is(extra.selfdetails, ROBOTS_URL, "violation's `selfdetails` is correct");
|
||||
is(extra.sourcetype, "chromeuri", "violation's `sourcetype` is correct");
|
||||
ok(
|
||||
extra.sourcedetails.endsWith("/browser_csp_violation_telemetry.js"),
|
||||
"violation's `sourcedetails` is correct"
|
||||
);
|
||||
is(extra.blockeduritype, "inline", "violation's `blockeduritype` is correct");
|
||||
is(
|
||||
extra.blockeduridetails,
|
||||
undefined,
|
||||
"violation's `blockeduridetails` is correct"
|
||||
);
|
||||
is(extra.linenumber, "18", "violation's `linenumber` is correct");
|
||||
is(extra.columnnumber, "45", "violation's `columnnumber` is correct");
|
||||
is(extra.sample, "foobar()", "violation's sample is correct");
|
||||
});
|
||||
@@ -315,6 +315,69 @@ security:
|
||||
(Only for violations from chrome:)
|
||||
type: string
|
||||
|
||||
csp_violation_internal_page:
|
||||
type: event
|
||||
description: >
|
||||
Information about Content-Security-Policy violations that happen in internal pages like chrome://
|
||||
bugs:
|
||||
- https://bugzil.la/1942622
|
||||
data_reviews:
|
||||
- https://bugzil.la/1942622
|
||||
notification_emails:
|
||||
- tschuster@mozilla.com
|
||||
- freddy@mozilla.com
|
||||
expires: never
|
||||
extra_keys:
|
||||
directive:
|
||||
description: >
|
||||
The same as SecurityPolicyViolationEvent's effectiveDirective.
|
||||
type: string
|
||||
selftype:
|
||||
description: >
|
||||
The sanitized type of the "self uri", which is roughly similar to the documentURI.
|
||||
This follows eval_usage_system_context sanitization procedure.
|
||||
type: string
|
||||
selfdetails:
|
||||
description: >
|
||||
A sanitized version of the "self uri", which is roughly similar to the documentURI,
|
||||
e.g. the whole chrome:// URL in some cases.
|
||||
This follows eval_usage_system_context sanitization procedure.
|
||||
type: string
|
||||
sourcetype:
|
||||
description: >
|
||||
The sanitized type of SecurityPolicyViolationEvent's sourceFile,
|
||||
e.g. "chromeuri".
|
||||
This follows eval_usage_system_context sanitization procedure.
|
||||
type: string
|
||||
sourcedetails:
|
||||
description: >
|
||||
A sanitized version of SecurityPolicyViolationEvent's sourceFile,
|
||||
e.g. the whole chrome:// URL in some cases.
|
||||
This follows eval_usage_system_context sanitization procedure.
|
||||
type: string
|
||||
blockeduritype:
|
||||
description: >
|
||||
The sanitized type of SecurityPolicyViolationEvent's blockedURI.
|
||||
type: string
|
||||
blockeduridetails:
|
||||
description: >
|
||||
A sanitized version of SecurityPolicyViolationEvent's blockedURI.
|
||||
type: string
|
||||
linenumber:
|
||||
description: >
|
||||
The same as SecurityPolicyViolationEvent's lineNumber.
|
||||
type: quantity
|
||||
columnnumber:
|
||||
description: >
|
||||
The same as SecurityPolicyViolationEvent's columnNumber.
|
||||
type: quantity
|
||||
sample:
|
||||
description: >
|
||||
The same as SecurityPolicyViolationEvent's sample.
|
||||
(Only for violations from chrome:)
|
||||
type: string
|
||||
|
||||
|
||||
eval_usage_parent_process:
|
||||
type: event
|
||||
description: >
|
||||
|
||||
@@ -44,12 +44,13 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs_security.h"
|
||||
#include "mozilla/dom/CSPReportBinding.h"
|
||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||
#include "mozilla/dom/CSPReportBinding.h"
|
||||
#include "mozilla/dom/CSPViolationReportBody.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/dom/ReportingUtils.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/glean/DomSecurityMetrics.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsIScriptElement.h"
|
||||
@@ -1428,6 +1429,59 @@ nsresult nsCSPContext::SendReportsToURIs(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsCSPContext::RecordInternalViolationTelemetry(
|
||||
const CSPViolationData& aCSPViolationData,
|
||||
const SecurityPolicyViolationEventInit& aInit) {
|
||||
if (!mSelfURI || !mSelfURI->SchemeIs("chrome")) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString selfURISpec;
|
||||
mSelfURI->GetSpec(selfURISpec);
|
||||
|
||||
// Temporarily skip this until we remove csp_violation_browser.
|
||||
if (selfURISpec.EqualsLiteral("chrome://browser/content/browser.xhtml")) {
|
||||
return;
|
||||
}
|
||||
|
||||
glean::security::CspViolationInternalPageExtra extra;
|
||||
extra.directive = Some(NS_ConvertUTF16toUTF8(aInit.mEffectiveDirective));
|
||||
|
||||
FilenameTypeAndDetails self =
|
||||
nsContentSecurityUtils::FilenameToFilenameType(selfURISpec, true);
|
||||
extra.selftype = Some(self.first);
|
||||
extra.selfdetails = self.second;
|
||||
|
||||
FilenameTypeAndDetails source =
|
||||
nsContentSecurityUtils::FilenameToFilenameType(
|
||||
NS_ConvertUTF16toUTF8(aInit.mSourceFile), true);
|
||||
extra.sourcetype = Some(source.first);
|
||||
extra.sourcedetails = source.second;
|
||||
|
||||
extra.linenumber = Some(aInit.mLineNumber);
|
||||
extra.columnnumber = Some(aInit.mColumnNumber);
|
||||
|
||||
// Don't collect samples for code that is probably not shipped by us.
|
||||
if (source.first.EqualsLiteral("chromeuri") ||
|
||||
source.first.EqualsLiteral("resourceuri") ||
|
||||
source.first.EqualsLiteral("abouturi")) {
|
||||
// aInit's sample requires the 'report-sample' keyword.
|
||||
extra.sample = Some(NS_ConvertUTF16toUTF8(aCSPViolationData.mSample));
|
||||
}
|
||||
|
||||
if (aInit.mBlockedURI.EqualsLiteral("inline")) {
|
||||
extra.blockeduritype = Some("inline"_ns);
|
||||
} else {
|
||||
FilenameTypeAndDetails blocked =
|
||||
nsContentSecurityUtils::FilenameToFilenameType(
|
||||
NS_ConvertUTF16toUTF8(aInit.mBlockedURI), true);
|
||||
extra.blockeduritype = Some(blocked.first);
|
||||
extra.blockeduridetails = blocked.second;
|
||||
}
|
||||
|
||||
glean::security::csp_violation_internal_page.Record(Some(extra));
|
||||
}
|
||||
|
||||
nsresult nsCSPContext::FireViolationEvent(
|
||||
Element* aTriggeringElement, nsICSPEventListener* aCSPEventListener,
|
||||
const mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit) {
|
||||
@@ -1561,7 +1615,10 @@ class CSPReportSenderRunnable final : public Runnable {
|
||||
// 3) log to console (one per policy violation)
|
||||
ReportToConsole();
|
||||
|
||||
// 4) fire violation event
|
||||
// 4) For internal pages we might send the failure to telemetry.
|
||||
mCSPContext->RecordInternalViolationTelemetry(mCSPViolationData, init);
|
||||
|
||||
// 5) fire violation event
|
||||
// A frame-ancestors violation has occurred, but we should not dispatch
|
||||
// the violation event to a potentially cross-origin ancestor.
|
||||
if (!mViolatedDirectiveName.EqualsLiteral("frame-ancestors")) {
|
||||
|
||||
@@ -106,6 +106,11 @@ class nsCSPContext : public nsIContentSecurityPolicy {
|
||||
const mozilla::dom::SecurityPolicyViolationEventInit&
|
||||
aViolationEventInit);
|
||||
|
||||
void RecordInternalViolationTelemetry(
|
||||
const mozilla::dom::CSPViolationData& aCSPViolationData,
|
||||
const mozilla::dom::SecurityPolicyViolationEventInit&
|
||||
aViolationEventInit);
|
||||
|
||||
nsresult FireViolationEvent(
|
||||
mozilla::dom::Element* aTriggeringElement,
|
||||
nsICSPEventListener* aCSPEventListener,
|
||||
|
||||
Reference in New Issue
Block a user