Skip to content

Commit

Permalink
Reland "Origin policy: implement window.originPolicyIds"
Browse files Browse the repository at this point in the history
This plumbs the origin policy IDs from the net-side OriginPolicyContents
through to the renderer, where they get exposed on Window. This does not
yet tackle WorkerGlobalScope, but it does add idlharness tests for it,
which fail for now.

This is a re-land of
https://chromium-review.googlesource.com/c/chromium/src/+/2089994 which
was reverted in
https://chromium-review.googlesource.com/c/chromium/src/+/2093453. The
re-land adds MSAN test expectations per https://crbug.com/856601.

Bug: 1057123
Change-Id: I30053986f3dfc634399c8e0f3fc1578e062c67f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095706
Auto-Submit: Domenic Denicola <domenic@chromium.org>
Commit-Queue: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748551}
  • Loading branch information
domenic authored and Commit Bot committed Mar 10, 2020
1 parent 9aaafe2 commit f21f4b7
Show file tree
Hide file tree
Showing 29 changed files with 349 additions and 2 deletions.
5 changes: 5 additions & 0 deletions content/renderer/render_frame_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,11 @@ void FillNavigationParamsOriginPolicy(
if (head.origin_policy.has_value() && head.origin_policy.value().contents) {
navigation_params->origin_policy = blink::WebOriginPolicy();

for (const auto& id : head.origin_policy.value().contents->ids) {
navigation_params->origin_policy->ids.emplace_back(
WebString::FromUTF8(id));
}

const base::Optional<std::string>& feature_policy =
head.origin_policy.value().contents->feature_policy;
if (feature_policy) {
Expand Down
1 change: 1 addition & 0 deletions services/network/public/cpp/network_ipc_param_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(network::IsolationOptInHints,
network::IsolationOptInHints::ALL_HINTS_ACTIVE)

IPC_STRUCT_TRAITS_BEGIN(network::OriginPolicyContents)
IPC_STRUCT_TRAITS_MEMBER(ids)
IPC_STRUCT_TRAITS_MEMBER(feature_policy)
IPC_STRUCT_TRAITS_MEMBER(content_security_policies)
IPC_STRUCT_TRAITS_MEMBER(content_security_policies_report_only)
Expand Down
3 changes: 3 additions & 0 deletions third_party/blink/public/web/web_origin_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ namespace blink {

// Origin Policy spec: https://wicg.github.io/origin-policy/
struct BLINK_EXPORT WebOriginPolicy {
// https://wicg.github.io/origin-policy/#origin-policy-ids
WebVector<WebString> ids;

// The feature policy that is dictated by the origin policy, if any.
// https://w3c.github.io/webappsec-feature-policy/
WebString feature_policy;
Expand Down
8 changes: 8 additions & 0 deletions third_party/blink/renderer/core/frame/local_dom_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,14 @@ void LocalDOMWindow::queueMicrotask(V8VoidFunction* callback) {
WrapPersistent(callback), nullptr));
}

const Vector<String>& LocalDOMWindow::originPolicyIds() const {
return origin_policy_ids_;
}

void LocalDOMWindow::SetOriginPolicyIds(const Vector<String>& ids) {
origin_policy_ids_ = ids;
}

int LocalDOMWindow::requestIdleCallback(V8IdleRequestCallback* callback,
const IdleRequestOptions* options) {
if (Document* document = this->document()) {
Expand Down
6 changes: 6 additions & 0 deletions third_party/blink/renderer/core/frame/local_dom_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
void queueMicrotask(V8VoidFunction*);

// https://wicg.github.io/origin-policy/#monkeypatch-html-windoworworkerglobalscope
const Vector<String>& originPolicyIds() const;
void SetOriginPolicyIds(const Vector<String>&);

// Idle callback extensions
int requestIdleCallback(V8IdleRequestCallback*, const IdleRequestOptions*);
void cancelIdleCallback(int id);
Expand Down Expand Up @@ -364,6 +368,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
String status_;
String default_status_;

Vector<String> origin_policy_ids_;

mutable Member<ApplicationCache> application_cache_;

scoped_refptr<SerializedScriptValue> pending_state_object_;
Expand Down
2 changes: 2 additions & 0 deletions third_party/blink/renderer/core/frame/window.idl
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@

// WindowOrWorkerGlobalScope mixin
// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
// https://wicg.github.io/origin-policy/#monkeypatch-html-windoworworkerglobalscope
[Replaceable] readonly attribute DOMString origin;
void queueMicrotask(VoidFunction callback);
[RuntimeEnabled=OriginPolicy, SameObject, SaveSameObject] readonly attribute FrozenArray<DOMString> originPolicyIds;

// AnimationFrameProvider mixin
// https://html.spec.whatwg.org/C/#animation-frames
Expand Down
10 changes: 10 additions & 0 deletions third_party/blink/renderer/core/loader/document_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

Expand Down Expand Up @@ -1564,6 +1565,15 @@ void DocumentLoader::InstallNewDocument(
if (frame_->GetDocument())
frame_->GetDocument()->RemoveAllEventListenersRecursively();
frame_->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(*frame_));
if (origin_policy_.has_value()) {
// Convert from WebVector<WebString> to WTF::Vector<WTF::String>
Vector<String> ids;
for (const auto& id : origin_policy_->ids) {
ids.push_back(id);
}

frame_->DomWindow()->SetOriginPolicyIds(ids);
}
}

if (!loading_url_as_javascript_)
Expand Down
4 changes: 4 additions & 0 deletions third_party/blink/web_tests/MSANExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ crbug.com/856601 [ Linux ] virtual/audio-service/external/wpt/mediacapture-strea
crbug.com/856601 [ Linux ] external/wpt/netinfo/idlharness.any.worker.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.html [ Pass Failure Timeout ]
crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.serviceworker.html [ Timeout Pass ]
crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.serviceworker.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.sharedworker.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.worker.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/permissions/interfaces.any.worker.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/pointerevents/idlharness.window.html [ Pass Timeout ]
crbug.com/856601 [ Linux ] external/wpt/presentation-api/controlling-ua/idlharness.https.html [ Pass Timeout ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// META: global=window,worker
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js

'use strict';

idl_test(
['origin-policy'],
['html', 'dom'],
idl_array => {
if (self.Window) {
idl_array.add_objects({ Window: ['self'] });
} else {
idl_array.add_objects({ WorkerGlobalScope: ['self'] });
}
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member that occurs after a non-empty "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op13",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op12",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy must include valid IDs and exclude non-strings and invalid strings</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op15",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"my-policy-1",
"my-policy-2",
"~",
" ",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"azAZ",
"my~policy"
]
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with no "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op11",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy a non-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op14",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return the same object each time</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script>
"use strict";
test(() => {
// Failing this test is a common failure mode for FrozenArray attributes,
// so let's be sure implementations get it right.
assert_equals(window.originPolicyIds, window.originPolicyIds);
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return an empty array in http: pages</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script>
"use strict";
test(() => {
assert_equals(location.protocol, "http:");
}, "Prerequisite check: running on HTTP, not HTTPS");

test(() => {
assert_array_equals(window.originPolicyIds, []);
}, "The attribute is still present and returns an empty frozen array");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy second "ids" member must take precedence</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>

<div id="log"></div>

<script>
"use strict";
runTestsInSubframe({
hostname: "op16",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"3",
"4"
]
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"ids": [
"this should be overwritten by the subsequent one"
],
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ids": "this is not an array",
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"ids": [
"my-policy-1",
["my-policy-array"],
5,
null,
{ "id": "my-policy-object" },
"my-policy-2",
true,
"~",
" ",
"\u0000",
"\t",
"my\tpolicy",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"my\u007Fpolicy",
"azAZ",
"my\u0080policy",
"my~policy",
"my\u1234policy"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"ids": [
"1",
"2"
],
"ids": [
"3",
"4"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
window.runTestsInSubframe = ({ hostname, testJS }) => {
window.runTestsInSubframe = ({ hostname, testJS, expectedIds }) => {
test(() => {
assert_equals(location.protocol, "https:");
}, "Prerequisite check: running on HTTPS");
Expand All @@ -12,6 +12,8 @@ window.runTestsInSubframe = ({ hostname, testJS }) => {
// to themselves.
url.searchParams.append("test", new URL(testJS, document.baseURI).pathname);

url.searchParams.append("expectedIds", JSON.stringify(expectedIds));

const iframe = document.createElement("iframe");
iframe.src = url.href;

Expand Down
Loading

0 comments on commit f21f4b7

Please sign in to comment.