Commit 46ca9af6 authored by Yifan Luo's avatar Yifan Luo Committed by Commit Bot

[Trusted Types] JS event tracking for policy creation

Add a new event listener `beforecreatepolicy` to
TrustedTypePolicyFactory::createPolicy which allow
people to track or block the creation process for
Trusted Types.

Bug: 1075601
Change-Id: Ib885e7adc740999ba0e39037b7f4a90af6ff6aef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2260594
Commit-Queue: Yifan Luo <lyf@chromium.org>
Reviewed-by: default avatarDaniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789409}
parent f5f1e618
......@@ -180,6 +180,7 @@ static_idl_files_in_core = get_path_info(
"//third_party/blink/renderer/core/events/animation_playback_event_init.idl",
"//third_party/blink/renderer/core/events/application_cache_error_event.idl",
"//third_party/blink/renderer/core/events/application_cache_error_event_init.idl",
"//third_party/blink/renderer/core/events/before_create_policy_event.idl",
"//third_party/blink/renderer/core/events/before_unload_event.idl",
"//third_party/blink/renderer/core/events/clipboard_event.idl",
"//third_party/blink/renderer/core/events/clipboard_event_init.idl",
......
......@@ -305,6 +305,7 @@ generate_event_interfaces("core_event_interfaces") {
"events/animation_event.idl",
"events/animation_playback_event.idl",
"events/application_cache_error_event.idl",
"events/before_create_policy_event.idl",
"events/before_unload_event.idl",
"events/clipboard_event.idl",
"events/composition_event.idl",
......
......@@ -146,6 +146,7 @@ core_interface_idl_files_core_only =
"events/animation_event.idl",
"events/animation_playback_event.idl",
"events/application_cache_error_event.idl",
"events/before_create_policy_event.idl",
"events/before_unload_event.idl",
"events/clipboard_event.idl",
"events/composition_event.idl",
......
......@@ -235,6 +235,10 @@ bool Event::IsBeforeTextInsertedEvent() const {
return false;
}
bool Event::IsBeforeCreatePolicyEvent() const {
return false;
}
bool Event::IsBeforeUnloadEvent() const {
return false;
}
......
......@@ -227,6 +227,7 @@ class CORE_EXPORT Event : public ScriptWrappable {
virtual bool IsClipboardEvent() const;
virtual bool IsBeforeTextInsertedEvent() const;
virtual bool IsBeforeCreatePolicyEvent() const;
virtual bool IsBeforeUnloadEvent() const;
virtual bool IsErrorEvent() const;
......
......@@ -13,6 +13,8 @@ blink_core_sources("events") {
"animation_playback_event.h",
"application_cache_error_event.cc",
"application_cache_error_event.h",
"before_create_policy_event.cc",
"before_create_policy_event.h",
"before_print_event.h",
"before_text_inserted_event.cc",
"before_text_inserted_event.h",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "before_create_policy_event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/event_type_names.h"
namespace blink {
BeforeCreatePolicyEvent* BeforeCreatePolicyEvent::Create(
const String& policy_name) {
return MakeGarbageCollected<BeforeCreatePolicyEvent>(policy_name);
}
BeforeCreatePolicyEvent::BeforeCreatePolicyEvent(const String& policy_name)
: Event(event_type_names::kBeforecreatepolicy,
Bubbles::kNo,
Cancelable::kYes),
policy_name_(policy_name) {}
BeforeCreatePolicyEvent::~BeforeCreatePolicyEvent() = default;
bool BeforeCreatePolicyEvent::IsBeforeCreatePolicyEvent() const {
return true;
}
const AtomicString& BeforeCreatePolicyEvent::InterfaceName() const {
return event_interface_names::kBeforeCreatePolicyEvent;
}
void BeforeCreatePolicyEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
} // namespace blink
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_BEFORE_CREATE_POLICY_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_BEFORE_CREATE_POLICY_EVENT_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class CORE_EXPORT BeforeCreatePolicyEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
static BeforeCreatePolicyEvent* Create(const String&);
explicit BeforeCreatePolicyEvent(const String&);
~BeforeCreatePolicyEvent() override;
bool IsBeforeCreatePolicyEvent() const override;
void setPolicyName(const String& policy_name) { policy_name_ = policy_name; }
String policyName() const { return policy_name_; }
const AtomicString& InterfaceName() const override;
void Trace(Visitor*) const override;
private:
String policy_name_;
};
template <>
struct DowncastTraits<BeforeCreatePolicyEvent> {
static bool AllowFrom(const Event& event) {
return event.IsBeforeCreatePolicyEvent();
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_BEFORE_CREATE_POLICY_EVENT_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://github.com/w3c/webappsec-trusted-types/issues/270#issue-579152412
[RuntimeEnabled=TrustedTypeBeforePolicyCreationEvent, Exposed=Window]
interface BeforeCreatePolicyEvent : Event {
attribute DOMString policyName;
};
\ No newline at end of file
......@@ -25,6 +25,7 @@
"TextTrack",
"TextTrackCue",
"TextTrackList",
"TrustedTypePolicyFactory",
"VideoTrackList",
"ApplicationCache",
"MojoInterfaceInterceptor",
......
......@@ -46,6 +46,7 @@
"backgroundfetchsuccess",
"beforematch",
"beforecopy",
"beforecreatepolicy",
"beforecut",
"beforeinput",
"beforeinstallprompt",
......
......@@ -9,6 +9,9 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_html.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script_url.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/before_create_policy_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
......@@ -17,6 +20,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
namespace blink {
......@@ -25,6 +29,16 @@ TrustedTypePolicy* TrustedTypePolicyFactory::createPolicy(
const String& policy_name,
const TrustedTypePolicyOptions* policy_options,
ExceptionState& exception_state) {
if (RuntimeEnabledFeatures::TrustedTypeBeforePolicyCreationEventEnabled()) {
DispatchEventResult result =
DispatchEvent(*BeforeCreatePolicyEvent::Create(policy_name));
if (result != DispatchEventResult::kNotCanceled) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotAllowedError,
"The policy creation has been canceled.");
return nullptr;
}
}
if (!GetExecutionContext()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The document is detached.");
......@@ -308,8 +322,16 @@ void TrustedTypePolicyFactory::CountTrustedTypeAssignmentError() {
}
}
const AtomicString& TrustedTypePolicyFactory::InterfaceName() const {
return event_target_names::kTrustedTypePolicyFactory;
}
ExecutionContext* TrustedTypePolicyFactory::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
void TrustedTypePolicyFactory::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
visitor->Trace(empty_html_);
visitor->Trace(empty_script_);
......
......@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_FACTORY_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
......@@ -22,7 +23,7 @@ class TrustedTypePolicy;
class TrustedTypePolicyOptions;
class CORE_EXPORT TrustedTypePolicyFactory final
: public ScriptWrappable,
: public EventTargetWithInlineData,
public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(TrustedTypePolicyFactory);
......@@ -37,6 +38,8 @@ class CORE_EXPORT TrustedTypePolicyFactory final
TrustedTypePolicy* defaultPolicy() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecreatepolicy, kBeforecreatepolicy)
bool isHTML(ScriptState*, const ScriptValue&);
bool isScript(ScriptState*, const ScriptValue&);
bool isScriptURL(ScriptState*, const ScriptValue&);
......@@ -68,6 +71,8 @@ class CORE_EXPORT TrustedTypePolicyFactory final
// relate it to the total number of TT enabled documents.)
void CountTrustedTypeAssignmentError();
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
void Trace(Visitor*) const override;
private:
......
......@@ -7,7 +7,7 @@
[
Exposed=(Window, Worker),
RuntimeEnabled=TrustedDOMTypes
] interface TrustedTypePolicyFactory {
] interface TrustedTypePolicyFactory : EventTarget {
[RaisesException] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions);
readonly attribute TrustedTypePolicy defaultPolicy;
// All the policy object names that have been created
......@@ -24,4 +24,6 @@
DOMString? getAttributeType(DOMString tagName, DOMString attribute,
optional DOMString elementNS, optional DOMString attrNs);
[CallWith=ScriptState] object? getTypeMapping(optional DOMString ns);
[RuntimeEnabled=TrustedTypeBeforePolicyCreationEvent] attribute EventHandler onbeforecreatepolicy;
};
......@@ -1840,6 +1840,10 @@
name: "TrustedDOMTypes",
status: "stable",
},
{
name: "TrustedTypeBeforePolicyCreationEvent",
status: "experimental",
},
{
name: "TrustTokens",
origin_trial_feature_name: "TrustTokens",
......
......@@ -28,7 +28,7 @@ typedef [StringContext=TrustedScriptURL] USVString ScriptURLString;
[
Exposed=(Window, Worker),
SecureContext
] interface TrustedTypePolicyFactory {
] interface TrustedTypePolicyFactory : EventTarget {
TrustedTypePolicy createPolicy(DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
// All the policy object names that have been created
};
......
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
<meta http-equiv="Content-Security-Policy" content="trusted-types *">
<body>
<script>
test(t => {
event_listener = (e) => {
assert_equals(e.policyName, "default");
e.preventDefault(); // don't let this policy be created.
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
assert_throws_dom("NotAllowedError", () => trustedTypes.createPolicy("default", {}));
}, 'Block Trusted Type policy creation by event listener.');
test(t => {
let flag = false;
event_listener = (e) => {
assert_equals(e.policyName, "myPolicy");
flag = true;
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
trustedTypes.createPolicy("myPolicy", {});
assert_equals(flag, true);
}, 'Trusted Type policy creation.');
test(t => {
event_listener = (e) => {
if (e.policyName === "default")
e.preventDefault();
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
assert_throws_dom("NotAllowedError", () => trustedTypes.createPolicy("default", {}));
trustedTypes.createPolicy("newPolicy", {});
}, 'Block only default Trusted Type policy creation.');
test(t => {
event_listener = (e) => {
assert_unreached();
};
trustedTypes.createPolicy("test", {});
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
}, 'Policy creation called before addEventListener function will not reached the listener.');
</script>
\ No newline at end of file
......@@ -116,6 +116,7 @@ PASS window.cached_statusbar.visible is false
PASS window.cached_styleMedia.type is ''
PASS window.cached_toolbar.visible is false
PASS window.cached_trustedTypes.defaultPolicy is null
PASS window.cached_trustedTypes.onbeforecreatepolicy is null
PASS window.cached_visualViewport.height is 0
PASS window.cached_visualViewport.offsetLeft is 0
PASS window.cached_visualViewport.offsetTop is 0
......
......@@ -116,6 +116,7 @@ PASS window.cached_statusbar.visible is false
PASS window.cached_styleMedia.type is ''
PASS window.cached_toolbar.visible is false
PASS window.cached_trustedTypes.defaultPolicy is null
PASS window.cached_trustedTypes.onbeforecreatepolicy is null
PASS window.cached_visualViewport.height is 0
PASS window.cached_visualViewport.offsetLeft is 0
PASS window.cached_visualViewport.offsetTop is 0
......
......@@ -116,6 +116,7 @@ PASS window.cached_statusbar.visible is false
PASS window.cached_styleMedia.type is ''
PASS window.cached_toolbar.visible is false
PASS window.cached_trustedTypes.defaultPolicy is null
PASS window.cached_trustedTypes.onbeforecreatepolicy is null
PASS window.cached_visualViewport.height is 0
PASS window.cached_visualViewport.offsetLeft is 0
PASS window.cached_visualViewport.offsetTop is 0
......
......@@ -254,6 +254,7 @@ PASS oldChildWindow.statusbar.visible is newChildWindow.statusbar.visible
PASS oldChildWindow.styleMedia.type is newChildWindow.styleMedia.type
PASS oldChildWindow.toolbar.visible is newChildWindow.toolbar.visible
PASS oldChildWindow.trustedTypes.defaultPolicy is newChildWindow.trustedTypes.defaultPolicy
PASS oldChildWindow.trustedTypes.onbeforecreatepolicy is newChildWindow.trustedTypes.onbeforecreatepolicy
PASS oldChildWindow.visualViewport.height is newChildWindow.visualViewport.height
PASS oldChildWindow.visualViewport.offsetLeft is newChildWindow.visualViewport.offsetLeft
PASS oldChildWindow.visualViewport.offsetTop is newChildWindow.visualViewport.offsetTop
......
......@@ -195,6 +195,7 @@ PASS childWindow.statusbar.visible is false
PASS childWindow.styleMedia.type is ''
PASS childWindow.toolbar.visible is false
PASS childWindow.trustedTypes.defaultPolicy is null
PASS childWindow.trustedTypes.onbeforecreatepolicy is null
PASS childWindow.visualViewport.height is 0
PASS childWindow.visualViewport.offsetLeft is 0
PASS childWindow.visualViewport.offsetTop is 0
......
......@@ -195,6 +195,7 @@ PASS childWindow.statusbar.visible is false
PASS childWindow.styleMedia.type is ''
PASS childWindow.toolbar.visible is false
PASS childWindow.trustedTypes.defaultPolicy is null
PASS childWindow.trustedTypes.onbeforecreatepolicy is null
PASS childWindow.visualViewport.height is 0
PASS childWindow.visualViewport.offsetLeft is 0
PASS childWindow.visualViewport.offsetTop is 0
......
......@@ -1495,11 +1495,12 @@ interface TransformStream
getter readable
getter writable
method constructor
interface TrustedTypePolicyFactory
interface TrustedTypePolicyFactory : EventTarget
attribute @@toStringTag
getter defaultPolicy
getter emptyHTML
getter emptyScript
getter onbeforecreatepolicy
method constructor
method createPolicy
method getAttributeType
......@@ -1508,6 +1509,7 @@ interface TrustedTypePolicyFactory
method isHTML
method isScript
method isScriptURL
setter onbeforecreatepolicy
interface URL
attribute @@toStringTag
getter hash
......
......@@ -1233,7 +1233,7 @@ interface TransformStream
getter readable
getter writable
method constructor
interface TrustedTypePolicyFactory
interface TrustedTypePolicyFactory : EventTarget
attribute @@toStringTag
getter defaultPolicy
getter emptyHTML
......
......@@ -1141,7 +1141,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter readable
[Worker] getter writable
[Worker] method constructor
[Worker] interface TrustedTypePolicyFactory
[Worker] interface TrustedTypePolicyFactory : EventTarget
[Worker] attribute @@toStringTag
[Worker] getter defaultPolicy
[Worker] getter emptyHTML
......
......@@ -7322,7 +7322,7 @@ interface TrustedTypePolicy
method createHTML
method createScript
method createScriptURL
interface TrustedTypePolicyFactory
interface TrustedTypePolicyFactory : EventTarget
attribute @@toStringTag
getter defaultPolicy
getter emptyHTML
......
......@@ -1141,7 +1141,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter readable
[Worker] getter writable
[Worker] method constructor
[Worker] interface TrustedTypePolicyFactory
[Worker] interface TrustedTypePolicyFactory : EventTarget
[Worker] attribute @@toStringTag
[Worker] getter defaultPolicy
[Worker] getter emptyHTML
......
......@@ -1473,11 +1473,12 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter readable
[Worker] getter writable
[Worker] method constructor
[Worker] interface TrustedTypePolicyFactory
[Worker] interface TrustedTypePolicyFactory : EventTarget
[Worker] attribute @@toStringTag
[Worker] getter defaultPolicy
[Worker] getter emptyHTML
[Worker] getter emptyScript
[Worker] getter onbeforecreatepolicy
[Worker] method constructor
[Worker] method createPolicy
[Worker] method getAttributeType
......@@ -1486,6 +1487,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method isHTML
[Worker] method isScript
[Worker] method isScriptURL
[Worker] setter onbeforecreatepolicy
[Worker] interface URL
[Worker] static method createObjectURL
[Worker] static method revokeObjectURL
......
......@@ -487,6 +487,11 @@ interface BatteryManager : EventTarget
setter onchargingtimechange
setter ondischargingtimechange
setter onlevelchange
interface BeforeCreatePolicyEvent : Event
attribute @@toStringTag
getter policyName
method constructor
setter policyName
interface BeforeInstallPromptEvent : Event
attribute @@toStringTag
getter platforms
......@@ -8522,11 +8527,12 @@ interface TrustedTypePolicy
method createHTML
method createScript
method createScriptURL
interface TrustedTypePolicyFactory
interface TrustedTypePolicyFactory : EventTarget
attribute @@toStringTag
getter defaultPolicy
getter emptyHTML
getter emptyScript
getter onbeforecreatepolicy
method constructor
method createPolicy
method getAttributeType
......@@ -8535,6 +8541,7 @@ interface TrustedTypePolicyFactory
method isHTML
method isScript
method isScriptURL
setter onbeforecreatepolicy
interface UIEvent : Event
attribute @@toStringTag
getter detail
......
......@@ -1372,11 +1372,12 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter readable
[Worker] getter writable
[Worker] method constructor
[Worker] interface TrustedTypePolicyFactory
[Worker] interface TrustedTypePolicyFactory : EventTarget
[Worker] attribute @@toStringTag
[Worker] getter defaultPolicy
[Worker] getter emptyHTML
[Worker] getter emptyScript
[Worker] getter onbeforecreatepolicy
[Worker] method constructor
[Worker] method createPolicy
[Worker] method getAttributeType
......@@ -1385,6 +1386,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method isHTML
[Worker] method isScript
[Worker] method isScriptURL
[Worker] setter onbeforecreatepolicy
[Worker] interface URL
[Worker] static method createObjectURL
[Worker] static method revokeObjectURL
......
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