Title: [149120] trunk
Revision
149120
Author
[email protected]
Date
2013-04-25 10:48:58 -0700 (Thu, 25 Apr 2013)

Log Message

Sec-WebSocket-Extensions header field must not appear more than once in an HTTP response.
https://bugs.webkit.org/show_bug.cgi?id=115128

Patch by Lamarque V. Souza <[email protected]> on 2013-04-25
Reviewed by Alexey Proskuryakov.

Source/WebCore:

According to WebSocket specification Sec-WebSocket-Extensions header field
must not appear more than once in an HTTP response. It is ok if it appears
more than once in client request. Also add a check for invalid UTF-8
characters when parsing Sec-WebSocket-Extensions quoted string.

Test: http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html

* Modules/websockets/WebSocketExtensionParser.cpp:
(WebCore::WebSocketExtensionParser::consumeQuotedString): Return false if there is
invalid character in the quoted string being parsed.
* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::readHTTPHeaders): Check if Sec-WebSocket-Extensions
appears more than once in header response. Abort handshake if it does.

LayoutTests:

* http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header_wsh.py: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (149119 => 149120)


--- trunk/LayoutTests/ChangeLog	2013-04-25 17:31:05 UTC (rev 149119)
+++ trunk/LayoutTests/ChangeLog	2013-04-25 17:48:58 UTC (rev 149120)
@@ -1,3 +1,14 @@
+2013-04-25  Lamarque V. Souza  <[email protected]>
+
+        Sec-WebSocket-Extensions header field must not appear more than once in an HTTP response.
+        https://bugs.webkit.org/show_bug.cgi?id=115128
+
+        Reviewed by Alexey Proskuryakov.
+
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header_wsh.py: Added.
+
 2013-04-25  Adrian Perez de Castro  <[email protected]>
 
         [GStreamer] Add audio/speex MIME type as supported

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt (0 => 149120)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt	2013-04-25 17:48:58 UTC (rev 149120)
@@ -0,0 +1,9 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-extensions-header' failed: The Sec-WebSocket-Extensions header MUST NOT appear more than once in an HTTP response
+Test that WebSocket handshake fails if there are more than one Sec-WebSocket-Extensions header field in the response..
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html (0 => 149120)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html	2013-04-25 17:48:58 UTC (rev 149120)
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Test that WebSocket handshake fails if there are more than one Sec-WebSocket-Extensions header field in the response..");
+
+window.jsTestIsAsync = true;
+
+function endTest()
+{
+    clearTimeout(timeoutID);
+    finishJSTest();
+}
+
+var url = ""
+var ws = new WebSocket(url);
+
+ws._onopen_ = function()
+{
+    testFailed("Unexpectedly Connected.");
+};
+
+ws._onmessage_ = function(messageEvent)
+{
+    testFailed("Unexpectedly Received: '" + messageEvent.data + "'");
+};
+
+ws._onclose_ = function()
+{
+    endTest();
+};
+
+function timeOutCallback()
+{
+    debug("Timed out in state: " + ws.readyState);
+    endTest();
+}
+
+var timeoutID = setTimeout(timeOutCallback, 3000);
+
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header_wsh.py (0 => 149120)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header_wsh.py	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header_wsh.py	2013-04-25 17:48:58 UTC (rev 149120)
@@ -0,0 +1,18 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+
+def web_socket_do_extra_handshake(request):
+    msg = 'HTTP/1.1 101 Switching Protocols\r\n'
+    msg += 'Upgrade: websocket\r\n'
+    msg += 'Connection: Upgrade\r\n'
+    msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    msg += 'Sec-WebSocket-Extensions: x-webkit-deflate-frame\r\n'
+    msg += 'Sec-WebSocket-Extensions: foo\r\n'
+    msg += '\r\n'
+    request.connection.write(msg)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Modified: trunk/Source/WebCore/ChangeLog (149119 => 149120)


--- trunk/Source/WebCore/ChangeLog	2013-04-25 17:31:05 UTC (rev 149119)
+++ trunk/Source/WebCore/ChangeLog	2013-04-25 17:48:58 UTC (rev 149120)
@@ -1,3 +1,24 @@
+2013-04-25  Lamarque V. Souza  <[email protected]>
+
+        Sec-WebSocket-Extensions header field must not appear more than once in an HTTP response.
+        https://bugs.webkit.org/show_bug.cgi?id=115128
+
+        Reviewed by Alexey Proskuryakov.
+
+        According to WebSocket specification Sec-WebSocket-Extensions header field
+        must not appear more than once in an HTTP response. It is ok if it appears
+        more than once in client request. Also add a check for invalid UTF-8
+        characters when parsing Sec-WebSocket-Extensions quoted string.
+
+        Test: http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header.html
+
+        * Modules/websockets/WebSocketExtensionParser.cpp:
+        (WebCore::WebSocketExtensionParser::consumeQuotedString): Return false if there is
+        invalid character in the quoted string being parsed.
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::readHTTPHeaders): Check if Sec-WebSocket-Extensions
+        appears more than once in header response. Abort handshake if it does.
+
 2013-04-25  Raphael Kubo da Costa  <[email protected]>
 
         REGRESSION(r148758): Remove WTFLogAlways call from IconLoader.

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketExtensionParser.cpp (149119 => 149120)


--- trunk/Source/WebCore/Modules/websockets/WebSocketExtensionParser.cpp	2013-04-25 17:31:05 UTC (rev 149119)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketExtensionParser.cpp	2013-04-25 17:48:58 UTC (rev 149120)
@@ -92,6 +92,8 @@
     if (m_current >= m_end || *m_current != '"')
         return false;
     m_currentToken = String::fromUTF8(buffer.data(), buffer.size());
+    if (m_currentToken.isNull())
+        return false;
     ++m_current;
     return true;
 }

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp (149119 => 149120)


--- trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2013-04-25 17:31:05 UTC (rev 149119)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2013-04-25 17:48:58 UTC (rev 149120)
@@ -465,6 +465,7 @@
 
     AtomicString name;
     String value;
+    bool sawSecWebSocketExtensionsHeaderField = false;
     bool sawSecWebSocketAcceptHeaderField = false;
     bool sawSecWebSocketProtocolHeaderField = false;
     const char* p = start;
@@ -478,13 +479,16 @@
         if (name.isEmpty())
             break;
 
-        // Sec-WebSocket-Extensions may be split. We parse and check the
-        // header value every time the header appears.
         if (equalIgnoringCase("sec-websocket-extensions", name)) {
+            if (sawSecWebSocketExtensionsHeaderField) {
+                m_failureReason = "The Sec-WebSocket-Extensions header MUST NOT appear more than once in an HTTP response";
+                return 0;
+            }
             if (!m_extensionDispatcher.processHeaderValue(value)) {
                 m_failureReason = m_extensionDispatcher.failureReason();
                 return 0;
             }
+            sawSecWebSocketExtensionsHeaderField = true;
         } else if (equalIgnoringCase("Sec-WebSocket-Accept", name)) {
             if (sawSecWebSocketAcceptHeaderField) {
                 m_failureReason = "The Sec-WebSocket-Accept header MUST NOT appear more than once in an HTTP response";
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to