Commit e8e9916c authored by Mike West's avatar Mike West Committed by Commit Bot

Trusted Types: First stab at TrustedScriptURL.

koto@ added [`TrustedScriptURL`][1] to the explainer as a mechanism to
distinguish URLs that directly lead to script execution (e.g. via
assignment to `<script>`'s `src` attribute). This patch is a first pass
at an implementation, along with restrictions on `script.src` so we can
test it out.

[1]: https://github.com/mikewest/trusted-types/commit/834163e519b579e5566908cafcedb2efe24be6da

Bug: 739170
Change-Id: Ie784ff3992dbcf750521fd55710befe3ed26036c
Reviewed-on: https://chromium-review.googlesource.com/677390
Commit-Queue: Mike West <mkwst@chromium.org>
Reviewed-by: default avatarYoav Weiss <yoav@yoav.ws>
Cr-Commit-Position: refs/heads/master@{#504306}
parent fed2d25e
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./support/helper.js"></script>
<script>
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.safe);
assert_equals(url.toString(), URLS.safe);
}, "Basic processing: safe URL, unsafe construction.");
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.javascript);
assert_equals(url.toString(), URLS.javascript);
}, "Basic processing: javascript URL, unsafe construction.");
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.external);
assert_equals(url.toString(), URLS.external);
}, "Basic processing: external protocol URL, unsafe construction.");
</script>
<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./support/helper.js"></script>
<meta http-equiv="Content-Security-Policy" content="require-trusted-types">
</head>
<body>
<script>
// String assignments throw.
test(t => {
var s = document.createElement('script');
assert_throws(new TypeError(), _ => {
s.src = URLS.safe;
});
assert_equals('', s.src);
}, "'string'");
// TrustedURL assignments throw.
test(t => {
var url = TrustedURL.unsafelyCreate(URLS.safe);
var s = document.createElement('script');
assert_throws(new TypeError(), _ => {
s.src = url;
});
assert_equals('', s.src);
}, "TrustedURL(safe)");
// TrustedScriptURL assignments work.
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.safe);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
}, "TrustedScriptURL(safe)");
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.javascript);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
}, "TrustedScriptURL(javascript)");
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.external);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
}, "TrustedScriptURL(external)");
</script>
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./support/helper.js"></script>
<body>
<script>
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.safe);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
});
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.javascript);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
});
test(t => {
var url = TrustedScriptURL.unsafelyCreate(URLS.external);
var s = document.createElement('script');
s.src = url;
assert_equals(url + '', s.src);
});
</script>
......@@ -1158,6 +1158,11 @@ interface TrustedHTML
attribute @@toStringTag
method constructor
method toString
interface TrustedScriptURL
static method unsafelyCreate
attribute @@toStringTag
method constructor
method toString
interface TrustedURL
static method create
static method unsafelyCreate
......
......@@ -1067,6 +1067,11 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] attribute @@toStringTag
[Worker] method constructor
[Worker] method toString
[Worker] interface TrustedScriptURL
[Worker] static method unsafelyCreate
[Worker] attribute @@toStringTag
[Worker] method constructor
[Worker] method toString
[Worker] interface TrustedURL
[Worker] static method create
[Worker] static method unsafelyCreate
......
......@@ -7002,6 +7002,11 @@ interface TrustedHTML
attribute @@toStringTag
method constructor
method toString
interface TrustedScriptURL
static method unsafelyCreate
attribute @@toStringTag
method constructor
method toString
interface TrustedURL
static method create
static method unsafelyCreate
......
......@@ -1067,6 +1067,11 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] attribute @@toStringTag
[Worker] method constructor
[Worker] method toString
[Worker] interface TrustedScriptURL
[Worker] static method unsafelyCreate
[Worker] attribute @@toStringTag
[Worker] method constructor
[Worker] method toString
[Worker] interface TrustedURL
[Worker] static method create
[Worker] static method unsafelyCreate
......
......@@ -73,6 +73,8 @@ bindings_core_generated_union_type_files = [
"$bindings_core_v8_output_dir/string_or_float.h",
"$bindings_core_v8_output_dir/string_or_trusted_html.cc",
"$bindings_core_v8_output_dir/string_or_trusted_html.h",
"$bindings_core_v8_output_dir/string_or_trusted_script_url.cc",
"$bindings_core_v8_output_dir/string_or_trusted_script_url.h",
"$bindings_core_v8_output_dir/string_or_trusted_url.cc",
"$bindings_core_v8_output_dir/string_or_trusted_url.h",
"$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.cc",
......
......@@ -128,6 +128,7 @@ core_idl_files =
"dom/events/Event.idl",
"dom/events/EventTarget.idl",
"dom/trustedtypes/TrustedHTML.idl",
"dom/trustedtypes/TrustedScriptURL.idl",
"dom/trustedtypes/TrustedURL.idl",
"editing/Selection.idl",
"events/AnimationEvent.idl",
......
......@@ -337,6 +337,8 @@ blink_core_sources("dom") {
"events/WindowEventContext.h",
"trustedtypes/TrustedHTML.cpp",
"trustedtypes/TrustedHTML.h",
"trustedtypes/TrustedScriptURL.cpp",
"trustedtypes/TrustedScriptURL.h",
"trustedtypes/TrustedURL.cpp",
"trustedtypes/TrustedURL.h",
]
......
......@@ -33,6 +33,7 @@
#include "bindings/core/v8/V8DOMActivityLogger.h"
#include "bindings/core/v8/scroll_into_view_options_or_boolean.h"
#include "bindings/core/v8/string_or_trusted_html.h"
#include "bindings/core/v8/string_or_trusted_script_url.h"
#include "core/CSSValueKeywords.h"
#include "core/SVGNames.h"
#include "core/XMLNames.h"
......@@ -81,6 +82,7 @@
#include "core/dom/WhitespaceAttacher.h"
#include "core/dom/events/EventDispatcher.h"
#include "core/dom/trustedtypes/TrustedHTML.h"
#include "core/dom/trustedtypes/TrustedScriptURL.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/EphemeralRange.h"
#include "core/editing/FrameSelection.h"
......@@ -1366,6 +1368,24 @@ void Element::SetSynchronizedLazyAttribute(const QualifiedName& name,
SetAttributeInternal(index, name, value, kInSynchronizationOfLazyAttribute);
}
void Element::setAttribute(const QualifiedName& name,
const StringOrTrustedScriptURL& stringOrURL,
ExceptionState& exception_state) {
DCHECK(stringOrURL.isString() ||
RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
if (stringOrURL.isString() && GetDocument().RequireTrustedTypes()) {
exception_state.ThrowTypeError(
"This document requires `TrustedScriptURL` assignment.");
return;
}
String valueString = stringOrURL.isString()
? stringOrURL.getAsString()
: stringOrURL.getAsTrustedScriptURL()->toString();
setAttribute(name, AtomicString(valueString));
}
ALWAYS_INLINE void Element::SetAttributeInternal(
size_t index,
const QualifiedName& name,
......@@ -3789,6 +3809,12 @@ KURL Element::GetURLAttribute(const QualifiedName& name) const {
StripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
}
void Element::GetURLAttribute(const QualifiedName& name,
StringOrTrustedScriptURL& result) const {
KURL url = GetURLAttribute(name);
result.setString(url.GetString());
}
KURL Element::GetNonEmptyURLAttribute(const QualifiedName& name) const {
#if DCHECK_IS_ON()
if (GetElementData()) {
......
......@@ -74,6 +74,7 @@ class ShadowRoot;
class ShadowRootInit;
class SpaceSplitString;
class StringOrTrustedHTML;
class StringOrTrustedScriptURL;
class StylePropertySet;
class StylePropertyMap;
class V0CustomElementDefinition;
......@@ -197,6 +198,12 @@ class CORE_EXPORT Element : public ContainerNode {
const AtomicString& value,
ExceptionState&);
void setAttribute(const AtomicString& name, const AtomicString& value);
// Trusted Type variant of the above.
void setAttribute(const QualifiedName&,
const StringOrTrustedScriptURL&,
ExceptionState&);
static bool ParseAttributeName(QualifiedName&,
const AtomicString& namespace_uri,
const AtomicString& qualified_name,
......@@ -553,6 +560,8 @@ class CORE_EXPORT Element : public ContainerNode {
KURL HrefURL() const;
KURL GetURLAttribute(const QualifiedName&) const;
void GetURLAttribute(const QualifiedName&, StringOrTrustedScriptURL&) const;
KURL GetNonEmptyURLAttribute(const QualifiedName&) const;
virtual const AtomicString ImageSourceURL() const;
......
// Copyright 2017 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 "core/dom/trustedtypes/TrustedScriptURL.h"
#include "core/dom/ExecutionContext.h"
#include "platform/bindings/ScriptState.h"
namespace blink {
TrustedScriptURL::TrustedScriptURL(const KURL& url) : url_(url) {}
TrustedScriptURL* TrustedScriptURL::unsafelyCreate(ScriptState* script_state,
const String& url) {
return TrustedScriptURL::Create(
ExecutionContext::From(script_state)->CompleteURL(url));
}
String TrustedScriptURL::toString() const {
return url_.GetString();
}
} // namespace blink
// Copyright 2017 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 TrustedScriptURL_h
#define TrustedScriptURL_h
#include "core/CoreExport.h"
#include "platform/bindings/ScriptWrappable.h"
#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "platform/wtf/text/WTFString.h"
namespace blink {
class ScriptState;
class CORE_EXPORT TrustedScriptURL final
: public GarbageCollectedFinalized<TrustedScriptURL>,
public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
static TrustedScriptURL* Create(const KURL& url) {
return new TrustedScriptURL(url);
}
// TrustedScriptURL.idl
String toString() const;
static TrustedScriptURL* unsafelyCreate(ScriptState*, const String& url);
DEFINE_INLINE_VIRTUAL_TRACE() {}
private:
TrustedScriptURL(const KURL&);
KURL url_;
};
} // namespace blink
#endif // TrustedScriptURL_h
// Copyright 2017 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.
typedef (DOMString or TrustedScriptURL) ScriptURLString;
[
Exposed=(Window,Worker),
RuntimeEnabled=TrustedDOMTypes
] interface TrustedScriptURL {
[CallWith=ScriptState] static TrustedScriptURL unsafelyCreate(DOMString url);
stringifier;
};
......@@ -23,7 +23,7 @@ class CORE_EXPORT TrustedURL final
public:
static TrustedURL* Create(const KURL& url) { return new TrustedURL(url); }
// CredentialsContainer.idl
// TrustedURL.idl
String toString() const;
static TrustedURL* create(ScriptState*, const String& url);
static TrustedURL* unsafelyCreate(ScriptState*, const String& url);
......
......@@ -20,7 +20,7 @@
// https://html.spec.whatwg.org/#the-script-element
interface HTMLScriptElement : HTMLElement {
[CEReactions, Reflect, URL] attribute DOMString src;
[CEReactions, Reflect, URL, RaisesException=Setter] attribute ScriptURLString src;
[CEReactions, Reflect] attribute DOMString type;
[CEReactions, Reflect, RuntimeEnabled=ModuleScripts] attribute boolean noModule;
[CEReactions, Reflect] attribute DOMString charset;
......
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