Title: [105076] trunk
Revision
105076
Author
[email protected]
Date
2012-01-16 10:42:03 -0800 (Mon, 16 Jan 2012)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=41210
Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header

Source/WebCore:

Parsing the "Access-Control-Expose-Headers" in the XMLHTTPRequest response header.
If the custom response-header is part of Access-Control-Expose-Headers, then consider that custom response-header as a valid one.

Patch by Joe Thomas <[email protected]> on 2012-01-16
Reviewed by Alexey Proskuryakov.

Test: http/tests/xmlhttprequest/access-control-response-with-expose-headers.html

* loader/CrossOriginAccessControl.cpp:
(WebCore::parseAccessControlExposeHeadersAllowList):  parsing logic of Access-Control-Expose-Headers
* loader/CrossOriginAccessControl.h:
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::getAllResponseHeaders): checking whether the custom response-header is part of "Access-Control-Expose-Headers"
(WebCore::XMLHttpRequest::getResponseHeader):  checking whether the custom response-header is part of "Access-Control-Expose-Headers"

LayoutTests:

Added test cases for Access-Control-Expose-Headers

Patch by Joe Thomas <[email protected]> on 2012-01-16
Reviewed by Alexey Proskuryakov.

* http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt: Added.
* http/tests/xmlhttprequest/access-control-response-with-expose-headers.html: Added.
* http/tests/xmlhttprequest/resources/access-control-response-with-expose-headers.php: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (105075 => 105076)


--- trunk/LayoutTests/ChangeLog	2012-01-16 18:40:21 UTC (rev 105075)
+++ trunk/LayoutTests/ChangeLog	2012-01-16 18:42:03 UTC (rev 105076)
@@ -1,3 +1,16 @@
+2012-01-16  Joe Thomas  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=41210
+        Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header
+
+        Added test cases for Access-Control-Expose-Headers
+
+        Reviewed by Alexey Proskuryakov.
+
+        * http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt: Added.
+        * http/tests/xmlhttprequest/access-control-response-with-expose-headers.html: Added.
+        * http/tests/xmlhttprequest/resources/access-control-response-with-expose-headers.php: Added.
+
 2012-01-16  Alexander Pavlov  <[email protected]>
 
         [Chromium] Unreviewed, rebaseline SVG tests after r105061.

Added: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt (0 => 105076)


--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt	2012-01-16 18:42:03 UTC (rev 105076)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: Refused to get unsafe header "X-TEST"
+Test for bug 41210: Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS xhr.getResponseHeader("X-FOO") is 'BAR'
+PASS xhr.getResponseHeader("x-foo") is 'BAR'
+PASS xhr.getResponseHeader("X-TEST") is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers.html (0 => 105076)


--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers.html	2012-01-16 18:42:03 UTC (rev 105076)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script type="text/_javascript_">
+window.jsTestIsAsync = true;
+description('Test for bug 41210: Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header.');
+var xhr = new XMLHttpRequest();
+xhr._onreadystatechange_=function() {
+    if (xhr.readyState==4) {
+        shouldBe("xhr.getResponseHeader(\"X-FOO\")","'BAR'");
+        shouldBe("xhr.getResponseHeader(\"x-foo\")","'BAR'");
+        shouldBeNull("xhr.getResponseHeader(\"X-TEST\")");
+        finishJSTest();
+    }
+}
+var url = ""
+xhr.open("GET",url);
+xhr.send(null);
+</script>
+<script src=""
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/xmlhttprequest/resources/access-control-response-with-expose-headers.php (0 => 105076)


--- trunk/LayoutTests/http/tests/xmlhttprequest/resources/access-control-response-with-expose-headers.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/resources/access-control-response-with-expose-headers.php	2012-01-16 18:42:03 UTC (rev 105076)
@@ -0,0 +1,10 @@
+<?php
+    header("Access-control-max-age: 0");
+    header("Access-control-allow-origin: *");
+    header("X-foo: BAR");
+    header("X-TEST: TEST");
+    header("Access-Control-Expose-Headers: x-Foo");
+    header("Content-Type: text/html");
+
+    print "echo"
+?>

Modified: trunk/Source/WebCore/ChangeLog (105075 => 105076)


--- trunk/Source/WebCore/ChangeLog	2012-01-16 18:40:21 UTC (rev 105075)
+++ trunk/Source/WebCore/ChangeLog	2012-01-16 18:42:03 UTC (rev 105076)
@@ -1,3 +1,22 @@
+2012-01-16  Joe Thomas  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=41210
+        Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header
+
+        Parsing the "Access-Control-Expose-Headers" in the XMLHTTPRequest response header.
+        If the custom response-header is part of Access-Control-Expose-Headers, then consider that custom response-header as a valid one.
+
+        Reviewed by Alexey Proskuryakov.
+
+        Test: http/tests/xmlhttprequest/access-control-response-with-expose-headers.html
+
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::parseAccessControlExposeHeadersAllowList):  parsing logic of Access-Control-Expose-Headers
+        * loader/CrossOriginAccessControl.h:
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::getAllResponseHeaders): checking whether the custom response-header is part of "Access-Control-Expose-Headers"
+        (WebCore::XMLHttpRequest::getResponseHeader):  checking whether the custom response-header is part of "Access-Control-Expose-Headers"
+
 2012-01-16  Pavel Feldman  <[email protected]>
 
         Web Inspector: timeline record bars may overlap with the records column

Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (105075 => 105076)


--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp	2012-01-16 18:40:21 UTC (rev 105075)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp	2012-01-16 18:42:03 UTC (rev 105076)
@@ -30,7 +30,6 @@
 #include "HTTPParsers.h"
 #include "ResourceResponse.h"
 #include "SecurityOrigin.h"
-#include <wtf/HashSet.h>
 #include <wtf/Threading.h>
 #include <wtf/text/AtomicString.h>
 #include <wtf/text/StringBuilder.h>
@@ -76,7 +75,6 @@
     return true;
 }
 
-typedef HashSet<String, CaseFoldingHash> HTTPHeaderSet;
 static PassOwnPtr<HTTPHeaderSet> createAllowedCrossOriginResponseHeadersSet()
 {
     OwnPtr<HTTPHeaderSet> headerSet = adoptPtr(new HashSet<String, CaseFoldingHash>);
@@ -171,4 +169,15 @@
     return true;
 }
 
+void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet& headerSet)
+{
+    Vector<String> headers;
+    headerValue.split(',', false, headers);
+    for (unsigned headerCount = 0; headerCount < headers.size(); headerCount++) {
+        String strippedHeader = headers[headerCount].stripWhiteSpace();
+        if (!strippedHeader.isEmpty())
+            headerSet.add(strippedHeader);
+    }
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (105075 => 105076)


--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h	2012-01-16 18:40:21 UTC (rev 105075)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h	2012-01-16 18:42:03 UTC (rev 105076)
@@ -30,9 +30,12 @@
 #include "ResourceHandle.h"
 #include "ResourceRequest.h"
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
+typedef HashSet<String, CaseFoldingHash> HTTPHeaderSet;
+
 class HTTPHeaderMap;
 class ResourceResponse;
 class SecurityOrigin;
@@ -46,6 +49,7 @@
 ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin*, StoredCredentials);
 
 bool passesAccessControlCheck(const ResourceResponse&, StoredCredentials, SecurityOrigin*, String& errorDescription);
+void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet&);
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (105075 => 105076)


--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp	2012-01-16 18:40:21 UTC (rev 105075)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp	2012-01-16 18:42:03 UTC (rev 105076)
@@ -892,6 +892,8 @@
 
     StringBuilder stringBuilder;
 
+    HTTPHeaderSet accessControlExposeHeaderSet;
+    parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-Control-Expose-Headers"), accessControlExposeHeaderSet);
     HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end();
     for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin(); it!= end; ++it) {
         // Hide Set-Cookie header fields from the XMLHttpRequest client for these reasons:
@@ -903,7 +905,7 @@
         if (isSetCookieHeader(it->first) && !securityOrigin()->canLoadLocalResources())
             continue;
 
-        if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(it->first))
+        if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(it->first) && !accessControlExposeHeaderSet.contains(it->first))
             continue;
 
         stringBuilder.append(it->first);
@@ -929,8 +931,11 @@
         logConsoleError(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
         return String();
     }
+    
+    HTTPHeaderSet accessControlExposeHeaderSet;
+    parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-Control-Expose-Headers"), accessControlExposeHeaderSet);
 
-    if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)) {
+    if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name) && !accessControlExposeHeaderSet.contains(name)) {
         logConsoleError(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
         return String();
     }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to