Commit 9de9580d authored by Daniel Vogelheim's avatar Daniel Vogelheim Committed by Chromium LUCI CQ

[Trusted Types] Store Trusted Types for main & isolated worlds.

The current implementation assumes that TT is shared between all users of
a DOM instance, so that the main world & extensions will "see" the same TT
instance. This isn't desirable, and also doesn't actually work, as the
attached bug demonstrates. This patch creates & stores separate TT
(namely, TTPolicyFactory) instances for each "world".

Bug: 1149364, 984979
Change-Id: I12351e9d475907891b8f547b9f4568f3056bb527
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2584771
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836587}
parent 775f33ab
......@@ -205,12 +205,22 @@ void LocalDOMWindow::SetCurrentEvent(Event* new_event) {
current_event_ = new_event;
}
TrustedTypePolicyFactory* LocalDOMWindow::trustedTypes() const {
if (!trusted_types_) {
trusted_types_ =
MakeGarbageCollected<TrustedTypePolicyFactory>(GetExecutionContext());
}
return trusted_types_.Get();
TrustedTypePolicyFactory* LocalDOMWindow::GetTrustedTypesForWorld(
const DOMWrapperWorld& world) const {
DCHECK(world.IsMainWorld() || world.IsIsolatedWorld());
DCHECK(IsMainThread());
auto iter = trusted_types_map_.find(&world);
if (iter != trusted_types_map_.end())
return iter->value;
return trusted_types_map_
.insert(&world, MakeGarbageCollected<TrustedTypePolicyFactory>(
GetExecutionContext()))
.stored_value->value;
}
TrustedTypePolicyFactory* LocalDOMWindow::trustedTypes(
ScriptState* script_state) const {
return GetTrustedTypesForWorld(script_state->World());
}
bool LocalDOMWindow::IsCrossSiteSubframe() const {
......@@ -814,7 +824,7 @@ void LocalDOMWindow::Reset() {
media_ = nullptr;
custom_elements_ = nullptr;
application_cache_ = nullptr;
trusted_types_ = nullptr;
trusted_types_map_.clear();
}
void LocalDOMWindow::SendOrientationChangeEvent() {
......@@ -2041,7 +2051,7 @@ void LocalDOMWindow::Trace(Visitor* visitor) const {
visitor->Trace(visualViewport_);
visitor->Trace(event_listener_observers_);
visitor->Trace(current_event_);
visitor->Trace(trusted_types_);
visitor->Trace(trusted_types_map_);
visitor->Trace(input_method_controller_);
visitor->Trace(spell_checker_);
visitor->Trace(text_suggestion_controller_);
......
......@@ -162,7 +162,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
FrameOrWorkerScheduler* GetScheduler() final;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) final;
TrustedTypePolicyFactory* GetTrustedTypes() const final {
return trustedTypes();
return GetTrustedTypesForWorld(*GetCurrentWorld());
}
ScriptWrappable* ToScriptWrappable() final { return this; }
void CountPotentialFeaturePolicyViolation(
......@@ -392,7 +392,9 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
Event* CurrentEvent() const;
void SetCurrentEvent(Event*);
TrustedTypePolicyFactory* trustedTypes() const;
TrustedTypePolicyFactory* trustedTypes(ScriptState*) const;
TrustedTypePolicyFactory* GetTrustedTypesForWorld(
const DOMWrapperWorld&) const;
// Returns true if this window is cross-site to the main frame. Defaults to
// false in a detached window.
......@@ -485,7 +487,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// We represent the "undefined" value as nullptr.
Member<Event> current_event_;
mutable Member<TrustedTypePolicyFactory> trusted_types_;
// Store TrustedTypesPolicyFactory, per DOMWrapperWorld.
mutable HeapHashMap<scoped_refptr<const DOMWrapperWorld>,
Member<TrustedTypePolicyFactory>>
trusted_types_map_;
// A dummy scheduler to return when the window is detached.
// All operations on it result in no-op, but due to this it's safe to
......
......@@ -212,7 +212,7 @@
readonly attribute boolean isSecureContext;
// TrustedTypes API: http://github.com/wicg/trusted-types
[RuntimeEnabled=TrustedDOMTypes] readonly attribute TrustedTypePolicyFactory trustedTypes;
[RuntimeEnabled=TrustedDOMTypes, CallWith=ScriptState] readonly attribute TrustedTypePolicyFactory trustedTypes;
};
Window includes GlobalEventHandlers;
......
ALERT: Case #1: Trigger TT error on main page.
CONSOLE ERROR: line 17: This document requires 'TrustedHTML' assignment.
ALERT: Case #2: Trigger TT error in main world, via test runner.
CONSOLE ERROR: This document requires 'TrustedHTML' assignment.
ALERT: Case #3: Trigger TT error in extension.
ALERT: Case #4: Set default policy on main page. Trigger TT error in main 0page.
CONSOLE ERROR: This document requires 'TrustedHTML' assignment.
ALERT: Case #5: Default policy on main page. Trigger TT error in extension
ALERT: Cleanup & done.
The majority of Trusted Types-related tests can be found in the WPT test suite. This particular test tests the interaction of Trusted Types with isolated worlds, which is not accessible from WPT tests.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'">
<script>
// The majority of Trusted Types-related tests can be found in the WPT
// test suite. This particular test tests the interaction of Trusted Types
// with isolated worlds, which is not accessible from WPT tests.
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
function trigger() {
try {
document.getElementById("target").innerHTML = "abc";
} catch {
}
}
function trigger_in_world() {
testRunner.evaluateScriptInIsolatedWorld(1, trigger.toString() + "trigger();");
}
function test() {
alert("Case #1: Trigger TT error on main page.");
trigger();
alert("Case #2: Trigger TT error in main world, via test runner.");
testRunner.setIsolatedWorldInfo(1, null, null);
trigger_in_world();
alert("Case #3: Trigger TT error in extension.");
testRunner.setIsolatedWorldInfo(1, 'chrome-extension://123', '');
trigger_in_world();
alert("Case #4: Set default policy on main page. Trigger TT error in main 0page.");
trustedTypes.createPolicy("default", { createHTML: x => x });
testRunner.setIsolatedWorldInfo(1, null, null);
trigger_in_world();
alert("Case #5: Default policy on main page. Trigger TT error in extension");
testRunner.setIsolatedWorldInfo(1, 'chrome-extension://123', '');
trigger_in_world();
alert("Cleanup & done.");
document.getElementById("target").textContent = "";
testRunner.setIsolatedWorldInfo(1, null, null);
testRunner.notifyDone();
}
</script>
</head>
<body onload='test();'>
<p>
The majority of Trusted Types-related tests can be found in the WPT
test suite. This particular test tests the interaction of Trusted Types
with isolated worlds, which is not accessible from WPT tests.
</p>
<p id="target"></p>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment