Commit 57e5929e authored by Andy Paicu's avatar Andy Paicu Committed by Commit Bot

Implemented: remove browsing context name on cross origin navigation

When updating the history after a cross-origin navigation, the HTML
Standard says: "If the browsing context is a top-level browsing context,
but not an auxiliary browsing context, then set the browsing context's
name to the empty string."

Currently we are not doing this which means there's potential
information leak.

Spec: https://html.spec.whatwg.org/multipage/browsers.html#resetBCName
I2I: https://groups.google.com/a/chromium.org/d/msg/blink-dev/fhUIycdlINU/RLVEOKaNAwAJ
Webkit change:  https://trac.webkit.org/changeset/209076/webkit

Bug: crbug.com/706350
Change-Id: I70cb3efcef06a3442ed4bf9ddd3733e24ccde19d
Reviewed-on: https://chromium-review.googlesource.com/645309
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506708}
parent 92b3016f
<!DOCTYPE html>
<html>
<script>
var url = new URL(window.location.href);
url.hostname = "{{GET[hostname]}}";
url.pathname = "/security/support/window-name-test.sub.html";
url.search = "shouldhavename={{GET[shouldhavename]}}&sendmessage={{GET[sendmessage]}}";
window.name = "test";
document.location = url.href;
</script>
</html>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script>
function process_test_result(passed, test_name) {
if ({{GET[sendmessage]}}) {
if (window.opener) {
window.opener.postMessage(passed, "*");
} else {
parent.postMessage(passed, "*");
}
} else {
test(function(t) {
assert_equals(passed, true);
}, test_name);
}
}
if ({{GET[shouldhavename]}}) {
process_test_result(window.name == "test", "Test that window name is present");
} else {
process_test_result(window.name == "", "Test that window name is not present");
}
</script>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "test" after a cross-origin auxiliary frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
t = async_test("Test that the window name is correct");
window.addEventListener("message", t.step_func_done(function(e) {
assert_equals(e.data, true);
}));
window.open("support/window-name-navigation.sub.html?hostname={{domains[www1]}}&shouldhavename=true&sendmessage=true");
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "" after a cross-origin main frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
document.location = "support/window-name-navigation.sub.html?hostname={{domains[www1]}}&shouldhavename=false&sendmessage=false";
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "test" after a cross-origin sub frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
t = async_test("Test that the window name is correct");
window.addEventListener("message", t.step_func_done(function(e) {
assert_equals(e.data, true);
}));
</script>
<iframe src="support/window-name-navigation.sub.html?hostname={{domains[www1]}}&shouldhavename=true&sendmessage=true";
</iframe>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "test" after a same-origin auxiliary frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
t = async_test("Test that the window name is correct");
window.addEventListener("message", t.step_func_done(function(e) {
assert_equals(e.data, true);
}));
window.open("support/window-name-navigation.sub.html?hostname={{host}}&shouldhavename=true&sendmessage=true");
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "test" after a same-origin main frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
document.location = "support/window-name-navigation.sub.html?hostname={{host}}&shouldhavename=true&sendmessage=false";
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<!-- window.name should equal "test" after a same-origin sub frame navigation. -->
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<script>
t = async_test("Test that the window name is correct");
window.addEventListener("message", t.step_func_done(function(e) {
assert_equals(e.data, true);
}));
</script>
<iframe src="support/window-name-navigation.sub.html?hostname={{host}}&shouldhavename=true&sendmessage=true";
</iframe>
</body>
</html>
......@@ -990,12 +990,11 @@ bool DocumentLoader::ShouldClearWindowName(
const LocalFrame& frame,
SecurityOrigin* previous_security_origin,
const Document& new_document) {
if (!previous_security_origin)
return false;
if (!frame.IsMainFrame())
return false;
if (frame.Loader().Opener())
if (!previous_security_origin || !frame.IsMainFrame() ||
frame.Loader().Opener() ||
(frame.GetPage() && frame.GetPage()->OpenedByDOM())) {
return false;
}
return !new_document.GetSecurityOrigin()->IsSameSchemeHostPort(
previous_security_origin);
......@@ -1087,12 +1086,7 @@ void DocumentLoader::InstallNewDocument(
}
if (ShouldClearWindowName(*frame_, previous_security_origin, *document)) {
// TODO(andypaicu): experimentalSetNullName will just record the fact
// that the name would be nulled and if the name is accessed after we will
// fire a UseCounter. If we decide to move forward with this change, we'd
// actually clean the name here.
// frame_->tree().setName(g_null_atom);
frame_->Tree().ExperimentalSetNulledName();
frame_->Tree().SetName(g_null_atom);
}
if (!overriding_url.IsEmpty())
......
......@@ -50,29 +50,9 @@ FrameTree::FrameTree(Frame* this_frame)
FrameTree::~FrameTree() {}
const AtomicString& FrameTree::GetName() const {
// TODO(andypaicu): remove this once we have gathered the data
if (experimental_set_nulled_name_) {
const LocalFrame* frame =
this_frame_->IsLocalFrame()
? ToLocalFrame(this_frame_)
: (Top().IsLocalFrame() ? ToLocalFrame(&Top()) : nullptr);
if (frame) {
UseCounter::Count(frame,
WebFeature::kCrossOriginMainFrameNulledNameAccessed);
if (!name_.IsEmpty()) {
UseCounter::Count(
frame, WebFeature::kCrossOriginMainFrameNulledNonEmptyNameAccessed);
}
}
}
return name_;
}
// TODO(andypaicu): remove this once we have gathered the data
void FrameTree::ExperimentalSetNulledName() {
experimental_set_nulled_name_ = true;
}
void FrameTree::SetName(const AtomicString& name,
ReplicationPolicy replication) {
if (replication == kReplicate) {
......@@ -91,8 +71,6 @@ void FrameTree::SetName(const AtomicString& name,
}
}
// TODO(andypaicu): remove this once we have gathered the data
experimental_set_nulled_name_ = false;
name_ = name;
}
......
......@@ -47,9 +47,6 @@ class CORE_EXPORT FrameTree final {
};
void SetName(const AtomicString&, ReplicationPolicy = kDoNotReplicate);
// TODO(andypaicu): remove this once we have gathered the data
void ExperimentalSetNulledName();
Frame* Parent() const;
Frame& Top() const;
Frame* NextSibling() const;
......@@ -74,9 +71,6 @@ class CORE_EXPORT FrameTree final {
AtomicString name_; // The actual frame name (may be empty).
mutable unsigned scoped_child_count_;
// TODO(andypaicu): remove this once we have gathered the data
bool experimental_set_nulled_name_;
};
} // namespace blink
......
......@@ -1443,7 +1443,6 @@ enum WebFeature {
kMagnetometerConstructor = 1907,
kOrientationSensorPopulateMatrix = 1908,
kWindowOpenWithInvalidURL = 1909,
kCrossOriginMainFrameNulledNameAccessed = 1910,
kMenuItemElementIconAttribute = 1911,
kWebkitCSSMatrixSetMatrixValue = 1912,
kWebkitCSSMatrixConstructFromString = 1913,
......@@ -1553,7 +1552,6 @@ enum WebFeature {
kSmoothScrollJSInterventionActivated = 2020,
kBudgetAPIGetCost = 2021,
kBudgetAPIGetBudget = 2022,
kCrossOriginMainFrameNulledNonEmptyNameAccessed = 2023,
kDeprecatedTimingFunctionStepMiddle = 2024,
kDocumentDomainSetWithNonDefaultPort = 2025,
kDocumentDomainSetWithDefaultPort = 2026,
......
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