Commit 9b05ec76 authored by Yifan Luo's avatar Yifan Luo Committed by Commit Bot

[Trusted Types] Sink name changes in violation reports.

1. Use space instead of a dot.
2. Use HTMLScriptElement and SVGScriptElement instead of script.
3. Use `|` instead of ` ` between sink name and string value.


Bug: 1058446
Change-Id: I84b555b50dcb839cc8455612f08d53f028fc607f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2120495
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@{#755319}
parent cfa91cd2
...@@ -1079,10 +1079,9 @@ static void GatherSecurityPolicyViolationEventData( ...@@ -1079,10 +1079,9 @@ static void GatherSecurityPolicyViolationEventData(
if (!sample_prefix.IsEmpty()) { if (!sample_prefix.IsEmpty()) {
sample.Append(sample_prefix.StripWhiteSpace().Left( sample.Append(sample_prefix.StripWhiteSpace().Left(
ContentSecurityPolicy::kMaxSampleLength)); ContentSecurityPolicy::kMaxSampleLength));
sample.Append("|");
} }
if (!script_source.IsEmpty()) { if (!script_source.IsEmpty()) {
if (!sample.IsEmpty())
sample.Append(" ");
sample.Append(script_source.StripWhiteSpace().Left( sample.Append(script_source.StripWhiteSpace().Left(
ContentSecurityPolicy::kMaxSampleLength)); ContentSecurityPolicy::kMaxSampleLength));
} }
......
...@@ -293,6 +293,10 @@ void HTMLScriptElement::SetScriptElementForBinding( ...@@ -293,6 +293,10 @@ void HTMLScriptElement::SetScriptElementForBinding(
element.SetHTMLScriptElement(this); element.SetHTMLScriptElement(this);
} }
ScriptElementBase::Type HTMLScriptElement::GetScriptElementType() {
return ScriptElementBase::Type::kHTMLScriptElement;
}
Element& HTMLScriptElement::CloneWithoutAttributesAndChildren( Element& HTMLScriptElement::CloneWithoutAttributesAndChildren(
Document& factory) const { Document& factory) const {
CreateElementFlags flags = CreateElementFlags flags =
......
...@@ -109,6 +109,8 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement, ...@@ -109,6 +109,8 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
void SetScriptElementForBinding( void SetScriptElementForBinding(
HTMLScriptElementOrSVGScriptElement&) override; HTMLScriptElementOrSVGScriptElement&) override;
Type GetScriptElementType() override;
Element& CloneWithoutAttributesAndChildren(Document&) const override; Element& CloneWithoutAttributesAndChildren(Document&) const override;
// https://w3c.github.io/webappsec-trusted-types/dist/spec/#script-scripttext // https://w3c.github.io/webappsec-trusted-types/dist/spec/#script-scripttext
......
...@@ -54,6 +54,9 @@ class MockScriptElementBase : public GarbageCollected<MockScriptElementBase>, ...@@ -54,6 +54,9 @@ class MockScriptElementBase : public GarbageCollected<MockScriptElementBase>,
void(HTMLScriptElementOrSVGScriptElement&)); void(HTMLScriptElementOrSVGScriptElement&));
MOCK_CONST_METHOD0(Loader, ScriptLoader*()); MOCK_CONST_METHOD0(Loader, ScriptLoader*());
ScriptElementBase::Type GetScriptElementType() override {
return ScriptElementBase::Type::kHTMLScriptElement;
}
void Trace(Visitor* visitor) override { ScriptElementBase::Trace(visitor); } void Trace(Visitor* visitor) override { ScriptElementBase::Trace(visitor); }
}; };
......
...@@ -38,6 +38,7 @@ ScriptLoader* ScriptLoaderFromElement(Element*); ...@@ -38,6 +38,7 @@ ScriptLoader* ScriptLoaderFromElement(Element*);
class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin { class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
public: public:
enum class Type { kHTMLScriptElement, kSVGScriptElement };
virtual bool AsyncAttributeValue() const = 0; virtual bool AsyncAttributeValue() const = 0;
virtual String CharsetAttributeValue() const = 0; virtual String CharsetAttributeValue() const = 0;
virtual String CrossOriginAttributeValue() const = 0; virtual String CrossOriginAttributeValue() const = 0;
...@@ -76,6 +77,8 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin { ...@@ -76,6 +77,8 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
virtual void DispatchLoadEvent() = 0; virtual void DispatchLoadEvent() = 0;
virtual void DispatchErrorEvent() = 0; virtual void DispatchErrorEvent() = 0;
virtual Type GetScriptElementType() = 0;
protected: protected:
ScriptLoader* InitializeScriptLoader(bool parser_inserted, ScriptLoader* InitializeScriptLoader(bool parser_inserted,
bool already_started); bool already_started);
......
...@@ -1044,6 +1044,7 @@ String ScriptLoader::GetScriptText() const { ...@@ -1044,6 +1044,7 @@ String ScriptLoader::GetScriptText() const {
if (child_text_content == script_text_internal_slot) if (child_text_content == script_text_internal_slot)
return child_text_content; return child_text_content;
return GetStringForScriptExecution(child_text_content, return GetStringForScriptExecution(child_text_content,
element_->GetScriptElementType(),
element_->GetDocument().ContextDocument()); element_->GetDocument().ContextDocument());
} }
......
...@@ -170,6 +170,10 @@ void SVGScriptElement::SetScriptElementForBinding( ...@@ -170,6 +170,10 @@ void SVGScriptElement::SetScriptElementForBinding(
element.SetSVGScriptElement(this); element.SetSVGScriptElement(this);
} }
ScriptElementBase::Type SVGScriptElement::GetScriptElementType() {
return ScriptElementBase::Type::kSVGScriptElement;
}
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
bool SVGScriptElement::IsAnimatableAttribute(const QualifiedName& name) const { bool SVGScriptElement::IsAnimatableAttribute(const QualifiedName& name) const {
if (name == svg_names::kTypeAttr || name == svg_names::kHrefAttr || if (name == svg_names::kTypeAttr || name == svg_names::kHrefAttr ||
......
...@@ -100,6 +100,8 @@ class SVGScriptElement final : public SVGElement, ...@@ -100,6 +100,8 @@ class SVGScriptElement final : public SVGElement,
void SetScriptElementForBinding( void SetScriptElementForBinding(
HTMLScriptElementOrSVGScriptElement&) override; HTMLScriptElementOrSVGScriptElement&) override;
Type GetScriptElementType() override;
Element& CloneWithoutAttributesAndChildren(Document&) const override; Element& CloneWithoutAttributesAndChildren(Document&) const override;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override { bool LayoutObjectIsNeeded(const ComputedStyle&) const override {
return false; return false;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h" #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_html.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
...@@ -100,12 +101,23 @@ String GetSamplePrefix(const ExceptionState& exception_state) { ...@@ -100,12 +101,23 @@ String GetSamplePrefix(const ExceptionState& exception_state) {
sample_prefix.Append("eval"); sample_prefix.Append("eval");
} else if (interface_name && property_name) { } else if (interface_name && property_name) {
sample_prefix.Append(interface_name); sample_prefix.Append(interface_name);
sample_prefix.Append("."); sample_prefix.Append(" ");
sample_prefix.Append(property_name); sample_prefix.Append(property_name);
} }
return sample_prefix.ToString(); return sample_prefix.ToString();
} }
const char* GetElementName(const ScriptElementBase::Type type) {
switch (type) {
case ScriptElementBase::Type::kHTMLScriptElement:
return "HTMLScriptElement";
case ScriptElementBase::Type::kSVGScriptElement:
return "SVGScriptElement";
}
NOTREACHED();
return "";
}
// Handle failure of a Trusted Type assignment. // Handle failure of a Trusted Type assignment.
// //
// If trusted type assignment fails, we need to // If trusted type assignment fails, we need to
...@@ -438,9 +450,11 @@ String TrustedTypesCheckFor(SpecificTrustedType type, ...@@ -438,9 +450,11 @@ String TrustedTypesCheckFor(SpecificTrustedType type,
return ""; return "";
} }
String CORE_EXPORT GetStringForScriptExecution(const String& script, String CORE_EXPORT
Document* doc) { GetStringForScriptExecution(const String& script,
return GetStringFromScriptHelper(script, doc, "script", "text", const ScriptElementBase::Type type,
Document* doc) {
return GetStringFromScriptHelper(script, doc, GetElementName(type), "text",
kScriptExecution, kScriptExecution,
kScriptExecutionAndDefaultPolicyFailed); kScriptExecutionAndDefaultPolicyFailed);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink { namespace blink {
...@@ -65,7 +66,9 @@ CORE_EXPORT String TrustedTypesCheckForScriptURL(const String&, ...@@ -65,7 +66,9 @@ CORE_EXPORT String TrustedTypesCheckForScriptURL(const String&,
// but with setup & error handling suitable for the asynchronous execution // but with setup & error handling suitable for the asynchronous execution
// cases. // cases.
String TrustedTypesCheckForJavascriptURLinNavigation(const String&, Document*); String TrustedTypesCheckForJavascriptURLinNavigation(const String&, Document*);
CORE_EXPORT String GetStringForScriptExecution(const String&, Document*); CORE_EXPORT String GetStringForScriptExecution(const String&,
ScriptElementBase::Type,
Document*);
// Determine whether a Trusted Types check is needed in this execution context. // Determine whether a Trusted Types check is needed in this execution context.
// //
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
}); });
assert_false(evil); assert_false(evil);
return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => { return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
assert_equals(e.sample, "eval evil = '12345678901234567890123456789012"); assert_equals(e.sample, "eval|evil = '12345678901234567890123456789012");
})); }));
}, "Unsafe eval violation sample is clipped to 40 characters."); }, "Unsafe eval violation sample is clipped to 40 characters.");
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
}); });
return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => { return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
assert_equals(e.sample.replace(/\n/g, ""), assert_equals(e.sample.replace(/\n/g, ""),
"eval (function anonymous(a,b) {return '1234"); "eval|(function anonymous(a,b) {return '1234");
})); }));
}, "Function constructor - the other kind of eval - is clipped."); }, "Function constructor - the other kind of eval - is clipped.");
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
}); });
assert_equals(a.innerHTML, ""); assert_equals(a.innerHTML, "");
return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => { return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
assert_equals(e.sample, "Element.innerHTML 1234567890123456789012345678901234567890"); assert_equals(e.sample, "Element innerHTML|1234567890123456789012345678901234567890");
})); }));
}, "Trusted Types violation sample is clipped to 40 characters excluded the sink name."); }, "Trusted Types violation sample is clipped to 40 characters excluded the sink name.");
</script> </script>
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
openWindow(t, "support/navigation-support.html"); openWindow(t, "support/navigation-support.html");
return Promise.all([ return Promise.all([
expectLoadedAsMessage("navigation-support.html"), expectLoadedAsMessage("navigation-support.html"),
expectViolationAsMessage("Location.href"), expectViolationAsMessage("Location href"),
]); ]);
}, "Navigate a window with javascript:-urls in enforcing mode."); }, "Navigate a window with javascript:-urls in enforcing mode.");
......
<!DOCTYPE html> <!DOCTYPE html>
<head> <head>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/content-security-policy/support/testharness-helper.js"></script> <script src="/content-security-policy/support/testharness-helper.js"></script>
...@@ -154,17 +155,25 @@ ...@@ -154,17 +155,25 @@
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("Element.innerHTML")) .then(expect_sample("Element innerHTML|abc"));
.then(expect_sample("abc"));
expect_throws(_ => { document.getElementById("div").innerHTML = "abc" }); expect_throws(_ => { document.getElementById("div").innerHTML = "abc" });
return p; return p;
}, "Trusted Type violation report: sample for .innerHTML assignment"); }, "Trusted Type violation report: sample for innerHTML assignment");
promise_test(t => { promise_test(t => {
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("HTMLScriptElement.src")); .then(expect_sample("HTMLScriptElement text|abc"));
expect_throws(_ => { document.getElementById("script").text = "abc" });
return p;
}, "Trusted Type violation report: sample for text assignment");
promise_test(t => {
let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("HTMLScriptElement src"));
expect_throws(_ => { document.getElementById("script").src = "" }); expect_throws(_ => { document.getElementById("script").src = "" });
return p; return p;
}, "Trusted Type violation report: sample for script.src assignment"); }, "Trusted Type violation report: sample for script.src assignment");
...@@ -173,18 +182,48 @@ ...@@ -173,18 +182,48 @@
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("HTMLElement.innerText")) .then(expect_sample("HTMLElement innerText|2+2;"));
.then(expect_sample("2+2;"));
expect_throws(_ => document.getElementById("script").innerText = "2+2;"); expect_throws(_ => document.getElementById("script").innerText = "2+2;");
return p; return p;
}, "Trusted Type violation report: sample for script innerText assignment"); }, "Trusted Type violation report: sample for script innerText assignment");
// TODO(lyf): https://crbug.com/1066791 Following tests which related to svg
// script element cause a flaky timeout in `linux-blink-rel`, following tests
// should be added back after the bug fix.
//
// TODO(lyf): https://crbug.com/1064598
// promise_test(t => {
// let p = Promise.resolve()
// .then(promise_violation("require-trusted-types-for 'script'"))
// .then(expect_blocked_uri("trusted-types-sink"))
// .then(expect_sample("SVGScriptElement href"));
// expect_throws(_ => { document.getElementById("svgscript").href.baseVal = "" });
// return p;
// }, "Trusted Type violation report: sample for SVGScriptElement href assignment");
//
// promise_test(t => {
// let p = Promise.resolve()
// .then(promise_violation("require-trusted-types-for 'script'"))
// .then(expect_blocked_uri("trusted-types-sink"))
// .then(expect_sample("Element setAttribute"));
// expect_throws(_ => { document.getElementById("svgscript").setAttribute('href', "test"); });
// return p;
// }, "Trusted Type violation report: sample for SVGScriptElement href assignment by setAttribute");
//
// promise_test(t => {
// let p = Promise.resolve()
// .then(promise_violation("require-trusted-types-for 'script'"))
// .then(expect_blocked_uri("trusted-types-sink"))
// .then(expect_sample("SVGScriptElement text"));
// expect_throws(_ => { document.getElementById("svgscript").insertBefore(document.createTextNode("Hello"), null) });
// return p;
// }, "Trusted Type violation report: sample for SVGScriptElement text assignment");
promise_test(t => { promise_test(t => {
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("eval")) .then(expect_sample("eval|2+2"))
.then(expect_sample("2+2"))
.then(promise_flush()); .then(promise_flush());
expect_throws(_ => eval("2+2")); expect_throws(_ => eval("2+2"));
flush(); flush();
...@@ -197,8 +236,7 @@ ...@@ -197,8 +236,7 @@
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("HTMLElement.innerText")) .then(expect_sample("HTMLElement innerText|abbb"))
.then(expect_sample("abbb"))
.then(e => assert_less_than(e.sample.length, 150)); .then(e => assert_less_than(e.sample.length, 150));
const value = "a" + "b".repeat(50000); const value = "a" + "b".repeat(50000);
expect_throws(_ => document.getElementById("script").innerText = value); expect_throws(_ => document.getElementById("script").innerText = value);
...@@ -216,8 +254,7 @@ ...@@ -216,8 +254,7 @@
let p = Promise.resolve() let p = Promise.resolve()
.then(promise_violation("require-trusted-types-for 'script'")) .then(promise_violation("require-trusted-types-for 'script'"))
.then(expect_blocked_uri("trusted-types-sink")) .then(expect_blocked_uri("trusted-types-sink"))
.then(expect_sample("HTMLScriptElement.src")) .then(expect_sample("HTMLScriptElement src|abc"));
.then(expect_sample("abc"));
expect_throws(_ => document.getElementById("customscript").src = "abc"); expect_throws(_ => document.getElementById("customscript").src = "abc");
return p; return p;
}, "Trusted Type violation report: sample for custom element assignment"); }, "Trusted Type violation report: sample for custom element assignment");
...@@ -229,4 +266,5 @@ ...@@ -229,4 +266,5 @@
<div id="div"></div> <div id="div"></div>
<script id="script"></script> <script id="script"></script>
<script id="customscript" is="custom-script" src="a"></script> <script id="customscript" is="custom-script" src="a"></script>
<svg><script id="svgscript"></script></svg>
</body> </body>
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