Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / security / DOMSecurityMonitor.cpp
blob2ec4998b0b31a639afa6a487922fea15ceef3290
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DOMSecurityMonitor.h"
8 #include "nsContentUtils.h"
10 #include "nsIChannel.h"
11 #include "nsILoadInfo.h"
12 #include "nsIPrincipal.h"
13 #include "nsIURI.h"
14 #include "nsJSUtils.h"
15 #include "xpcpublic.h"
17 #include "mozilla/BasePrincipal.h"
18 #include "mozilla/StaticPrefs_dom.h"
20 /* static */
21 void DOMSecurityMonitor::AuditParsingOfHTMLXMLFragments(
22 nsIPrincipal* aPrincipal, const nsAString& aFragment) {
23 // if the fragment parser (e.g. innerHTML()) is not called in chrome: code
24 // or any of our about: pages, then there is nothing to do here.
25 if (!aPrincipal->IsSystemPrincipal() && !aPrincipal->SchemeIs("about")) {
26 return;
29 // check if the fragment is empty, if so, we can return early.
30 if (aFragment.IsEmpty()) {
31 return;
34 // check if there is a JS caller, if not, then we can can return early here
35 // because we only care about calls to the fragment parser (e.g. innerHTML)
36 // originating from JS code.
37 nsAutoString filename;
38 uint32_t lineNum = 0;
39 uint32_t columnNum = 1;
40 JSContext* cx = nsContentUtils::GetCurrentJSContext();
41 if (!cx ||
42 !nsJSUtils::GetCallingLocation(cx, filename, &lineNum, &columnNum)) {
43 return;
46 // check if we should skip assertion. Please only ever set this pref to
47 // true if really needed for testing purposes.
48 if (mozilla::StaticPrefs::dom_security_skip_html_fragment_assertion()) {
49 return;
53 * WARNING: Do not add any new entries to the htmlFragmentAllowlist
54 * without proper review from a dom:security peer!
56 static nsLiteralCString htmlFragmentAllowlist[] = {
57 "chrome://global/content/elements/marquee.js"_ns,
58 nsLiteralCString(
59 "chrome://pocket/content/panels/js/vendor/jquery-2.1.1.min.js"),
60 nsLiteralCString("chrome://devtools/content/shared/sourceeditor/"
61 "codemirror/codemirror.bundle.js"),
62 nsLiteralCString(
63 "resource://activity-stream/data/content/activity-stream.bundle.js"),
64 nsLiteralCString("resource://devtools/client/debugger/src/components/"
65 "Editor/Breakpoint.js"),
66 nsLiteralCString("resource://devtools/client/debugger/src/components/"
67 "Editor/ColumnBreakpoint.js"),
68 nsLiteralCString(
69 "resource://devtools/client/shared/vendor/fluent-react.js"),
70 "resource://devtools/client/shared/vendor/react-dom.js"_ns,
71 nsLiteralCString(
72 "resource://devtools/client/shared/vendor/react-dom-dev.js"),
73 nsLiteralCString(
74 "resource://devtools/client/shared/widgets/FilterWidget.js"),
75 nsLiteralCString("resource://devtools/client/shared/widgets/tooltip/"
76 "inactive-css-tooltip-helper.js"),
77 "resource://devtools/client/shared/widgets/Spectrum.js"_ns,
78 "resource://gre/modules/narrate/VoiceSelect.sys.mjs"_ns,
79 "resource://normandy-vendor/ReactDOM.js"_ns,
80 // ------------------------------------------------------------------
81 // test pages
82 // ------------------------------------------------------------------
83 "chrome://mochikit/content/browser-harness.xhtml"_ns,
84 "chrome://mochikit/content/harness.xhtml"_ns,
85 "chrome://mochikit/content/tests/"_ns,
86 "chrome://mochitests/content/"_ns,
87 "chrome://reftest/content/"_ns,
90 for (const nsLiteralCString& allowlistEntry : htmlFragmentAllowlist) {
91 if (StringBeginsWith(NS_ConvertUTF16toUTF8(filename), allowlistEntry)) {
92 return;
96 nsAutoCString uriSpec;
97 aPrincipal->GetAsciiSpec(uriSpec);
99 // Ideally we should not call the fragment parser (e.g. innerHTML()) in
100 // chrome: code or any of our about: pages. If you hit that assertion,
101 // please do *not* add your filename to the allowlist above, but rather
102 // refactor your code.
103 fprintf(stderr,
104 "Do not call the fragment parser (e.g innerHTML()) in chrome code "
105 "or in about: pages, (uri: %s), (caller: %s, line: %d, col: %d), "
106 "(fragment: %s)",
107 uriSpec.get(), NS_ConvertUTF16toUTF8(filename).get(), lineNum,
108 columnNum, NS_ConvertUTF16toUTF8(aFragment).get());
110 xpc_DumpJSStack(true, true, false);
111 MOZ_ASSERT(false);
114 /* static */
115 void DOMSecurityMonitor::AuditUseOfJavaScriptURI(nsIChannel* aChannel) {
116 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
117 nsCOMPtr<nsIPrincipal> loadingPrincipal = loadInfo->GetLoadingPrincipal();
119 // We only ever have no loadingPrincipal in case of a new top-level load.
120 // The purpose of this assertion is to make sure we do not allow loading
121 // javascript: URIs in system privileged contexts. Hence there is nothing
122 // to do here in case there is no loadingPrincipal.
123 if (!loadingPrincipal) {
124 return;
127 // if the javascript: URI is not loaded by a system privileged context
128 // or an about: page, there there is nothing to do here.
129 if (!loadingPrincipal->IsSystemPrincipal() &&
130 !loadingPrincipal->SchemeIs("about")) {
131 return;
134 MOZ_ASSERT(false,
135 "Do not use javascript: URIs in chrome code or in about: pages");