Source/WebCore: Never override the policy URL on form submissions.
authorjochen@chromium.org <jochen@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Aug 2011 21:18:49 +0000 (21:18 +0000)
committerjochen@chromium.org <jochen@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Aug 2011 21:18:49 +0000 (21:18 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@92142 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/loading/redirect-methods-expected.txt
LayoutTests/http/tests/security/cookies/resources/set-a-cookie.php [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-main-frame.html [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking-user-action.html [new file with mode: 0644]
LayoutTests/http/tests/security/cookies/third-party-cookie-blocking.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h

index 64c4035..a470cc3 100644 (file)
@@ -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.
index 049f4be..667b7df 100644 (file)
@@ -24,8 +24,8 @@ frame "0" - didHandleOnloadEventsForFrame
 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" - didHandleOnloadEventsForFrame
 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" - didHandleOnloadEventsForFrame
 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" - didHandleOnloadEventsForFrame
 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 (file)
index 0000000..6fb976a
--- /dev/null
@@ -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 (file)
index 0000000..e2c35fa
--- /dev/null
@@ -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 (file)
index 0000000..a87dbde
--- /dev/null
@@ -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 (file)
index 0000000..87288ca
--- /dev/null
@@ -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 (file)
index 0000000..e2c35fa
--- /dev/null
@@ -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 (file)
index 0000000..aea79d6
--- /dev/null
@@ -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 (file)
index 0000000..dfde31c
--- /dev/null
@@ -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>
index 8dc8454..96288d5 100644 (file)
@@ -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.
index 47bb220..f3c8ab0 100644 (file)
@@ -1175,7 +1175,7 @@ void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri
         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::detachViewsAndDocumentLoader()
     
 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 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String
     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 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loa
 
         // 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 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loa
     }
     
     if (!addedExtraFields)
-        addExtraFieldsToRequest(request, m_loadType, true, formData);
+        addExtraFieldsToRequest(request, m_loadType, true);
 
     loadWithNavigationAction(request, action, false, loadType, 0);
 }
index a236fbc..472a3ac 100644 (file)
@@ -301,7 +301,7 @@ private:
     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>);