Commit e17b6057 authored by abarth@webkit.org's avatar abarth@webkit.org

WebCore:

2008-09-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Sam Weinig.

        Adopt opener restriction on frame navigation.
          https://bugs.webkit.org/show_bug.cgi?id=20642

        This restriction helps prevent an attacker from navigating top-level
        windows that were created by another web site.

        Tests: http/tests/security/frameNavigation/not-opener.html
               http/tests/security/frameNavigation/opener.html

        * loader/FrameLoader.cpp:
        (WebCore::canAccessAncestor):
        (WebCore::FrameLoader::shouldAllowNavigation):

LayoutTests:

2008-09-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Sam Weinig.

        Tests that opener restriction is working properly.
          https://bugs.webkit.org/show_bug.cgi?id=20642

        * http/tests/security/frameNavigation/not-opener-expected.txt: Added.
        * http/tests/security/frameNavigation/not-opener.html: Added.
        * http/tests/security/frameNavigation/opener-expected.txt: Copied from LayoutTests/fast/dom/Document/early-document-access-expected.txt.
        * http/tests/security/frameNavigation/opener.html: Added.
        * http/tests/security/frameNavigation/resources/not-opener-helper.html: Added.
        * http/tests/security/frameNavigation/resources/pass.html: Added.
        * http/tests/security/frameNavigation/resources/ready.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36262 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9b3a7e3c
2008-09-07 Adam Barth <abarth@webkit.org>
Reviewed by Sam Weinig.
Tests that opener restriction is working properly.
https://bugs.webkit.org/show_bug.cgi?id=20642
* http/tests/security/frameNavigation/not-opener-expected.txt: Added.
* http/tests/security/frameNavigation/not-opener.html: Added.
* http/tests/security/frameNavigation/opener-expected.txt: Copied from LayoutTests/fast/dom/Document/early-document-access-expected.txt.
* http/tests/security/frameNavigation/opener.html: Added.
* http/tests/security/frameNavigation/resources/not-opener-helper.html: Added.
* http/tests/security/frameNavigation/resources/pass.html: Added.
* http/tests/security/frameNavigation/resources/ready.html: Added.
=== End merge of squirrelfish-extreme ===
2008-09-04 Geoffrey Garen <ggaren@apple.com>
......
CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to initiate a navigation change for frame with URL http://127.0.0.1:8000/security/frameNavigation/resources/ready.html from frame with URL http://localhost:8000/security/frameNavigation/resources/not-opener-helper.html.
PASS
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
layoutTestController.setCanOpenWindows();
}
function log(msg) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(msg));
document.getElementById("console").appendChild(div);
}
var readyCount = 0;
window.addEventListener("message", function(e) {
if (e.data == "ready") {
++readyCount;
if (readyCount == 2) {
helper.postMessage("set", "*");
}
} else if (e.data == "pass") {
target.document.body.innerHTML = "Should have navigated this window. It should be still be same-origin.";
log("PASS");
target.close();
helper.postMessage("cleanup", "*");
} else if (e.data == "done") {
helper.close();
if (window.layoutTestController)
layoutTestController.notifyDone();
}
}, false);
window.onload = function() {
target = window.open("resources/ready.html", "targetWindow");
helper = window.open("http://localhost:8000/security/frameNavigation/resources/not-opener-helper.html");
}
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
layoutTestController.setCanOpenWindows();
}
function log(msg) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(msg));
document.getElementById("console").appendChild(div);
}
window.addEventListener("message", function(e) {
if (e.data == "ready") {
win.location = "resources/pass.html";
} else if (e.data == "pass") {
win.document.body.innerHTML = "Frame navigated back on-domain";
win.close();
log("PASS");
if (window.layoutTestController)
layoutTestController.notifyDone();
}
}, false);
window.onload = function() {
win = window.open("http://localhost:8000/security/frameNavigation/resources/ready.html", "targetFrame");
}
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
<script>
window.addEventListener("message", function(e) {
if (e.data == "set") {
win = window.open("http://127.0.0.1:8000/security/frameNavigation/resources/ready.html", "targetWindow");
} else if (e.data == "ready") {
opener.postMessage("pass", "*");
} else if (e.data == "cleanup") {
win.close();
opener.postMessage("done", "*");
}
}, false);
opener.postMessage("ready", "*");
</script>
Helper window.
<script>
opener.postMessage("pass", "*");
</script>
Sent message "pass"
<script>
opener.postMessage("ready", "*");
</script>
Sent message "ready"
2008-09-07 Adam Barth <abarth@webkit.org>
Reviewed by Sam Weinig.
Adopt opener restriction on frame navigation.
https://bugs.webkit.org/show_bug.cgi?id=20642
This restriction helps prevent an attacker from navigating top-level
windows that were created by another web site.
Tests: http/tests/security/frameNavigation/not-opener.html
http/tests/security/frameNavigation/opener.html
* loader/FrameLoader.cpp:
(WebCore::canAccessAncestor):
(WebCore::FrameLoader::shouldAllowNavigation):
2008-09-07 Dan Bernstein <mitz@apple.com>
Reviewed by Maciej Stachowiak.
......
......@@ -2447,34 +2447,60 @@ void FrameLoader::reload()
loadWithDocumentLoader(loader.get(), FrameLoadTypeReload, 0);
}
static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
{
// targetFrame can be NULL when we're trying to navigate a top-level frame
// that has a NULL opener.
if (!targetFrame)
return false;
for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
Document* ancestorDocument = ancestorFrame->document();
if (!ancestorDocument)
return true;
const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin();
if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
return true;
}
return false;
}
bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const
{
// The navigation change is safe if the active frame is:
// - in the same security origin as the target or one of the target's ancestors
// - in the same security origin as the target or one of the target's
// ancestors.
//
// Or the target frame is:
// - a top-level frame in the frame hierarchy
// - a top-level frame in the frame hierarchy and the active frame can
// navigate the target frame's opener per above.
if (!targetFrame)
return true;
// Performance optimization.
if (m_frame == targetFrame)
return true;
if (!targetFrame->tree()->parent())
// Let a frame navigate the top-level window that contains it. This is
// important to allow because it lets a site "frame-bust" (escape from a
// frame created by another web site).
if (targetFrame == m_frame->tree()->top())
return true;
Document* activeDocument = m_frame->document();
ASSERT(activeDocument);
const SecurityOrigin* activeSecurityOrigin = activeDocument->securityOrigin();
for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
Document* ancestorDocument = ancestorFrame->document();
if (!ancestorDocument)
return true;
const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin();
if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
return true;
}
// For top-level windows, check the opener.
if (!targetFrame->tree()->parent() && canAccessAncestor(activeSecurityOrigin, targetFrame->loader()->opener()))
return true;
// In general, check the frame's ancestors.
if (canAccessAncestor(activeSecurityOrigin, targetFrame))
return true;
Settings* settings = targetFrame->settings();
if (settings && !settings->privateBrowsingEnabled()) {
......
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