Source/WebCore: Never override the policy URL on form submissions.
https://bugs.webkit.org/show_bug.cgi?id=61809
Reviewed by Adam Barth.
Tests: http/tests/security/cookies/third-party-cookie-blocking-main-frame.html
http/tests/security/cookies/third-party-cookie-blocking-user-action.html
http/tests/security/cookies/third-party-cookie-blocking.html
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::addExtraFieldsToSubresourceRequest):
(WebCore::FrameLoader::addExtraFieldsToMainResourceRequest):
(WebCore::FrameLoader::addExtraFieldsToRequest):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::loadDifferentDocumentItem):
* loader/FrameLoader.h:
LayoutTests: Require explicit user action to override the policy URL on form submissions.
https://bugs.webkit.org/show_bug.cgi?id=61809
Reviewed by Adam Barth.
* http/tests/loading/redirect-methods-expected.txt:
* http/tests/security/cookies/resources/set-a-cookie.php: Added.
* http/tests/security/cookies/third-party-cookie-blocking-expected.txt: Added.
* http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt: Added.
* http/tests/security/cookies/third-party-cookie-blocking-main-frame.html: Added.
* http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt: Added.
* http/tests/security/cookies/third-party-cookie-blocking-user-action.html: Added.
* http/tests/security/cookies/third-party-cookie-blocking.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@92142 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 64c4035..a470cc3 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2011-08-01 Jochen Eisinger <jochen@chromium.org>
+
+ Require explicit user action to override the policy URL on form submissions.
+ https://bugs.webkit.org/show_bug.cgi?id=61809
+
+ Reviewed by Adam Barth.
+
+ * http/tests/loading/redirect-methods-expected.txt:
+ * http/tests/security/cookies/resources/set-a-cookie.php: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking-expected.txt: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking-main-frame.html: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking-user-action.html: Added.
+ * http/tests/security/cookies/third-party-cookie-blocking.html: Added.
+
2011-08-01 Anna Cavender <annacc@chromium.org>
media/track tests should be skipped on all platforms until feature is fully implemented.
diff --git a/LayoutTests/http/tests/loading/redirect-methods-expected.txt b/LayoutTests/http/tests/loading/redirect-methods-expected.txt
index 049f4be..667b7df 100644
--- a/LayoutTests/http/tests/loading/redirect-methods-expected.txt
+++ b/LayoutTests/http/tests/loading/redirect-methods-expected.txt
@@ -24,8 +24,8 @@
frame "0" - didFinishLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
frame "0" - didStartProvisionalLoadForFrame
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 301>
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 301>
frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
frame "0" - didCancelClientRedirectForFrame
@@ -54,8 +54,8 @@
frame "1" - didFinishLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
frame "1" - didStartProvisionalLoadForFrame
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 302>
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 302>
frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
frame "1" - didCancelClientRedirectForFrame
@@ -84,8 +84,8 @@
frame "2" - didFinishLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
frame "2" - didStartProvisionalLoadForFrame
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 303>
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 303>
frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
frame "2" - didCancelClientRedirectForFrame
@@ -114,8 +114,8 @@
frame "3" - didFinishLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
frame "3" - didStartProvisionalLoadForFrame
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
-http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 307>
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 307>
frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame
http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
frame "3" - didCancelClientRedirectForFrame
diff --git a/LayoutTests/http/tests/security/cookies/resources/set-a-cookie.php b/LayoutTests/http/tests/security/cookies/resources/set-a-cookie.php
new file mode 100644
index 0000000..6fb976a
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/resources/set-a-cookie.php
@@ -0,0 +1,22 @@
+<?php
+ setcookie("test_cookie", "1", 0, "/");
+?>
+<!DOCTYPE html>
+<html>
+<script>
+function checkCookie()
+{
+ if (document.cookie.indexOf("test_cookie=1") < 0)
+ document.getElementById("log").innerHTML += "Cookie is NOT set";
+ else
+ document.getElementById("log").innerHTML += "Cookie is set";
+ document.cookie = "test_cookie=0; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT";
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+<body onload="checkCookie()">
+<div id="log"></div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-expected.txt b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-expected.txt
new file mode 100644
index 0000000..e2c35fa
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-expected.txt
@@ -0,0 +1,7 @@
+
+
+
+--------
+Frame: 'iframe'
+--------
+Cookie is NOT set
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt
new file mode 100644
index 0000000..a87dbde
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt
@@ -0,0 +1 @@
+Cookie is set
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame.html b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame.html
new file mode 100644
index 0000000..87288ca
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<title>Checks that a POST resulting in a main frame navigation is not affected by third-party cookie rules</title>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+ layoutTestController.dumpChildFramesAsText();
+ layoutTestController.setAlwaysAcceptCookies(false);
+}
+
+function runTest()
+{
+ document.getElementById('form').submit();
+}
+</script>
+<body onload="runTest()">
+ <div>
+ <form id="form" action="http://localhost:8000/security/cookies/resources/set-a-cookie.php" method="POST">
+ <input type="submit" />
+ </form>
+ <iframe src="javascript:false" name="iframe"></iframe>
+ </div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt
new file mode 100644
index 0000000..e2c35fa
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt
@@ -0,0 +1,7 @@
+
+
+
+--------
+Frame: 'iframe'
+--------
+Cookie is NOT set
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action.html b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action.html
new file mode 100644
index 0000000..aea79d6
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<title>Checks that a user generated POST request does not circumvent third-party cookie rules</title>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+ layoutTestController.dumpChildFramesAsText();
+ layoutTestController.setAlwaysAcceptCookies(false);
+}
+
+function runTest()
+{
+ if (window.eventSender) {
+ // Click somewhere on the button!
+ var form = document.getElementById("form");
+ eventSender.mouseMoveTo(form.offsetLeft + 5, form.offsetTop + 5);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ }
+}
+</script>
+<body onload="runTest()">
+ <div>
+ <form id="form" action="http://localhost:8000/security/cookies/resources/set-a-cookie.php" method="POST" target="iframe">
+ <input type="submit" />
+ </form>
+ <iframe src="javascript:false" name="iframe"></iframe>
+ </div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking.html b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking.html
new file mode 100644
index 0000000..dfde31c
--- /dev/null
+++ b/LayoutTests/http/tests/security/cookies/third-party-cookie-blocking.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<title>Checks that a script generated POST request does not circumvent third-party cookie rules</title>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.waitUntilDone();
+ layoutTestController.dumpAsText();
+ layoutTestController.dumpChildFramesAsText();
+ layoutTestController.setAlwaysAcceptCookies(false);
+}
+
+function runTest()
+{
+ document.getElementById('form').submit();
+}
+</script>
+<body onload="runTest()">
+ <div>
+ <form id="form" action="http://localhost:8000/security/cookies/resources/set-a-cookie.php" method="POST" target="iframe">
+ <input type="submit" />
+ </form>
+ <iframe src="javascript:false" name="iframe"></iframe>
+ </div>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 8dc8454..96288d5 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2011-08-01 Jochen Eisinger <jochen@chromium.org>
+
+ Never override the policy URL on form submissions.
+ https://bugs.webkit.org/show_bug.cgi?id=61809
+
+ Reviewed by Adam Barth.
+
+ Tests: http/tests/security/cookies/third-party-cookie-blocking-main-frame.html
+ http/tests/security/cookies/third-party-cookie-blocking-user-action.html
+ http/tests/security/cookies/third-party-cookie-blocking.html
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadURL):
+ (WebCore::FrameLoader::addExtraFieldsToSubresourceRequest):
+ (WebCore::FrameLoader::addExtraFieldsToMainResourceRequest):
+ (WebCore::FrameLoader::addExtraFieldsToRequest):
+ (WebCore::FrameLoader::loadPostRequest):
+ (WebCore::FrameLoader::loadDifferentDocumentItem):
+ * loader/FrameLoader.h:
+
+
2011-08-01 Ryosuke Niwa <rniwa@webkit.org>
Update comment added in r92139 per Darin's suggestion.
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 47bb220..f3c8ab0 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1175,7 +1175,7 @@
RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer);
addHTTPOriginIfNeeded(request, referrerOrigin->toString());
}
- addExtraFieldsToRequest(request, newLoadType, true, event || isFormSubmission);
+ addExtraFieldsToRequest(request, newLoadType, true);
if (newLoadType == FrameLoadTypeReload || newLoadType == FrameLoadTypeReloadFromOrigin)
request.setCachePolicy(ReloadIgnoringCacheData);
@@ -2437,20 +2437,20 @@
void FrameLoader::addExtraFieldsToSubresourceRequest(ResourceRequest& request)
{
- addExtraFieldsToRequest(request, m_loadType, false, false);
+ addExtraFieldsToRequest(request, m_loadType, false);
}
void FrameLoader::addExtraFieldsToMainResourceRequest(ResourceRequest& request)
{
- addExtraFieldsToRequest(request, m_loadType, true, false);
+ addExtraFieldsToRequest(request, m_loadType, true);
}
-void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool mainResource, bool cookiePolicyURLFromRequest)
+void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool mainResource)
{
// Don't set the cookie policy URL if it's already been set.
// But make sure to set it on all requests, as it has significance beyond the cookie policy for all protocols (<rdar://problem/6616664>).
if (request.firstPartyForCookies().isEmpty()) {
- if (mainResource && (isLoadingMainFrame() || cookiePolicyURLFromRequest))
+ if (mainResource && isLoadingMainFrame())
request.setFirstPartyForCookies(request.url());
else if (Document* document = m_frame->document())
request.setFirstPartyForCookies(document->firstPartyForCookies());
@@ -2550,7 +2550,7 @@
workingResourceRequest.setHTTPMethod("POST");
workingResourceRequest.setHTTPBody(formData);
workingResourceRequest.setHTTPContentType(contentType);
- addExtraFieldsToRequest(workingResourceRequest, loadType, true, true);
+ addExtraFieldsToRequest(workingResourceRequest, loadType, true);
NavigationAction action(url, loadType, true, event);
@@ -3024,7 +3024,7 @@
// Make sure to add extra fields to the request after the Origin header is added for the FormData case.
// See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion.
- addExtraFieldsToRequest(request, m_loadType, true, formData);
+ addExtraFieldsToRequest(request, m_loadType, true);
addedExtraFields = true;
// FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
@@ -3067,7 +3067,7 @@
}
if (!addedExtraFields)
- addExtraFieldsToRequest(request, m_loadType, true, formData);
+ addExtraFieldsToRequest(request, m_loadType, true);
loadWithNavigationAction(request, action, false, loadType, 0);
}
diff --git a/Source/WebCore/loader/FrameLoader.h b/Source/WebCore/loader/FrameLoader.h
index a236fbc..472a3ac 100644
--- a/Source/WebCore/loader/FrameLoader.h
+++ b/Source/WebCore/loader/FrameLoader.h
@@ -301,7 +301,7 @@
void updateFirstPartyForCookies();
void setFirstPartyForCookies(const KURL&);
- void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType loadType, bool isMainResource, bool cookiePolicyURLFromRequest);
+ void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
void clearProvisionalLoad();
void transitionToCommitted(PassRefPtr<CachedPage>);