- Revision
- 264394
- Author
- lmo...@igalia.com
- Date
- 2020-07-15 06:48:26 -0700 (Wed, 15 Jul 2020)
Log Message
[SOUP] Artificial delay to WebSocket connection to mitigate port scanning attacks
https://bugs.webkit.org/show_bug.cgi?id=214293
Reviewed by Carlos Garcia Campos.
Source/WebKit:
r264306 added an artificial delay when NetworkSocketStream closed due
to closed ports but Soup-based ports use another code path and were
still returning immediately.
SOUP WebSocket errors do not distinguish closed ports separately, so
this commit checks for connections that finished with NOT_WEBSOCKET
errors.
Covered by existing tests.
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::randomClosedPortDelay): Move the delay
calculation here to be shared between the different code paths.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkSocketStream.cpp:
(WebKit::NetworkSocketStream::didFailSocketStream): Use the shared
delay.
(WebKit::randomDelay): Deleted.
* NetworkProcess/soup/WebSocketTaskSoup.cpp:
(WebKit::WebSocketTask::WebSocketTask): Add a oneShot timer with
random duration when failing to connect to something that is not a
WebSocket.
(WebKit::WebSocketTask::delayFailTimerFired):
LayoutTests:
Add glib-specific baseline due to SOUP messages.
* platform/glib/TestExpectations:
* platform/glib/http/tests/websocket/tests/hybi/closed-port-delay-expected.txt: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (264393 => 264394)
--- trunk/LayoutTests/ChangeLog 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/LayoutTests/ChangeLog 2020-07-15 13:48:26 UTC (rev 264394)
@@ -1,3 +1,15 @@
+2020-07-15 Lauro Moura <lmo...@igalia.com>
+
+ [SOUP] Artificial delay to WebSocket connection to mitigate port scanning attacks
+ https://bugs.webkit.org/show_bug.cgi?id=214293
+
+ Reviewed by Carlos Garcia Campos.
+
+ Add glib-specific baseline due to SOUP messages.
+
+ * platform/glib/TestExpectations:
+ * platform/glib/http/tests/websocket/tests/hybi/closed-port-delay-expected.txt: Added.
+
2020-07-15 Alicia Boya GarcĂa <ab...@igalia.com>
[MSE][GStreamer] Unreviewed micro gardening: imported/w3c/web-platform-tests/media-source/mediasource-changetype-play-negative.html
Modified: trunk/LayoutTests/platform/glib/TestExpectations (264393 => 264394)
--- trunk/LayoutTests/platform/glib/TestExpectations 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2020-07-15 13:48:26 UTC (rev 264394)
@@ -362,8 +362,6 @@
# SOUP-related bugs
#////////////////////////////////////////////////////////////////////////////////////////
-webkit.org/b/214293 http/tests/websocket/tests/hybi/closed-port-delay.html [ Failure ]
-
#////////////////////////////////////////////////////////////////////////////////////////
# End of SOUP-related bugs
#////////////////////////////////////////////////////////////////////////////////////////
Added: trunk/LayoutTests/platform/glib/http/tests/websocket/tests/hybi/closed-port-delay-expected.txt (0 => 264394)
--- trunk/LayoutTests/platform/glib/http/tests/websocket/tests/hybi/closed-port-delay-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/glib/http/tests/websocket/tests/hybi/closed-port-delay-expected.txt 2020-07-15 13:48:26 UTC (rev 264394)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: The server did not accept the WebSocket handshake.
+CONSOLE MESSAGE: The server did not accept the WebSocket handshake.
+CONSOLE MESSAGE: The server did not accept the WebSocket handshake.
+Tests that WebSocket close report is delayed to mitigate port scanning attacks.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Successfully delayed reporting of closed WebSocket connection
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: trunk/Source/WebKit/ChangeLog (264393 => 264394)
--- trunk/Source/WebKit/ChangeLog 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/ChangeLog 2020-07-15 13:48:26 UTC (rev 264394)
@@ -1,3 +1,34 @@
+2020-07-15 Lauro Moura <lmo...@igalia.com>
+
+ [SOUP] Artificial delay to WebSocket connection to mitigate port scanning attacks
+ https://bugs.webkit.org/show_bug.cgi?id=214293
+
+ Reviewed by Carlos Garcia Campos.
+
+ r264306 added an artificial delay when NetworkSocketStream closed due
+ to closed ports but Soup-based ports use another code path and were
+ still returning immediately.
+
+ SOUP WebSocket errors do not distinguish closed ports separately, so
+ this commit checks for connections that finished with NOT_WEBSOCKET
+ errors.
+
+ Covered by existing tests.
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::randomClosedPortDelay): Move the delay
+ calculation here to be shared between the different code paths.
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkSocketStream.cpp:
+ (WebKit::NetworkSocketStream::didFailSocketStream): Use the shared
+ delay.
+ (WebKit::randomDelay): Deleted.
+ * NetworkProcess/soup/WebSocketTaskSoup.cpp:
+ (WebKit::WebSocketTask::WebSocketTask): Add a oneShot timer with
+ random duration when failing to connect to something that is not a
+ WebSocket.
+ (WebKit::WebSocketTask::delayFailTimerFired):
+
2020-07-14 Per Arne Vollan <pvol...@apple.com>
[iOS] Add missing messages to message filter in WebContent sandbox
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (264393 => 264394)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2020-07-15 13:48:26 UTC (rev 264394)
@@ -2777,6 +2777,13 @@
completionHandler();
}
+static constexpr auto delayMax = 100_ms;
+static constexpr auto delayMin = 10_ms;
+Seconds NetworkProcess::randomClosedPortDelay()
+{
+ return delayMin + Seconds::fromMilliseconds(static_cast<double>(cryptographicallyRandomNumber())) % delayMax;
+}
+
void NetworkProcess::hasAppBoundSession(PAL::SessionID sessionID, CompletionHandler<void(bool)>&& completionHandler) const
{
bool result = false;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (264393 => 264394)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2020-07-15 13:48:26 UTC (rev 264394)
@@ -353,6 +353,8 @@
void resetServiceWorkerFetchTimeoutForTesting(CompletionHandler<void()>&&);
Seconds serviceWorkerFetchTimeout() const { return m_serviceWorkerFetchTimeout; }
+ static Seconds randomClosedPortDelay();
+
void cookieAcceptPolicyChanged(WebCore::HTTPCookieAcceptPolicy);
void hasAppBoundSession(PAL::SessionID, CompletionHandler<void(bool)>&&) const;
void clearAppBoundSession(PAL::SessionID, CompletionHandler<void()>&&);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp (264393 => 264394)
--- trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp 2020-07-15 13:48:26 UTC (rev 264394)
@@ -103,15 +103,8 @@
send(Messages::WebSocketStream::DidUpdateBufferedAmount(amount));
}
-static constexpr auto delayMax = 100_ms;
-static constexpr auto delayMin = 10_ms;
static constexpr auto closedPortErrorCode = 61;
-static Seconds randomDelay()
-{
- return delayMin + Seconds::fromMilliseconds(static_cast<double>(cryptographicallyRandomNumber())) % delayMax;
-}
-
void NetworkSocketStream::sendDelayedFailMessage()
{
send(Messages::WebSocketStream::DidFailSocketStream(m_closedPortError));
@@ -123,7 +116,7 @@
if (error.errorCode() == closedPortErrorCode) {
m_closedPortError = error;
- m_delayFailTimer.startOneShot(randomDelay());
+ m_delayFailTimer.startOneShot(NetworkProcess::randomClosedPortDelay());
} else
send(Messages::WebSocketStream::DidFailSocketStream(error));
}
Modified: trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp (264393 => 264394)
--- trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp 2020-07-15 13:48:26 UTC (rev 264394)
@@ -32,6 +32,7 @@
#include <WebCore/ResourceRequest.h>
#include <WebCore/ResourceResponse.h>
#include <WebCore/WebSocketChannel.h>
+#include <wtf/RunLoop.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/StringBuilder.h>
@@ -41,6 +42,7 @@
: m_channel(channel)
, m_handshakeMessage(msg)
, m_cancellable(adoptGRef(g_cancellable_new()))
+ , m_delayFailTimer(RunLoop::main(), this, &WebSocketTask::delayFailTimerFired)
{
auto protocolList = protocol.split(',');
GUniquePtr<char*> protocols;
@@ -63,6 +65,14 @@
if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
auto* task = static_cast<WebSocketTask*>(userData);
+ if (g_error_matches(error.get(), SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET)
+ && task->m_handshakeMessage
+ && (task->m_handshakeMessage->status_code == SOUP_STATUS_CANT_CONNECT
+ || task->m_handshakeMessage->status_code == SOUP_STATUS_CANT_CONNECT_PROXY)) {
+ task->m_delayErrorMessage = String::fromUTF8(error->message);
+ task->m_delayFailTimer.startOneShot(NetworkProcess::randomClosedPortDelay());
+ return;
+ }
if (connection)
task->didConnect(WTFMove(connection));
else
@@ -240,4 +250,9 @@
{
}
+void WebSocketTask::delayFailTimerFired()
+{
+ didFail(m_delayErrorMessage);
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h (264393 => 264394)
--- trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h 2020-07-15 13:05:02 UTC (rev 264393)
+++ trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h 2020-07-15 13:48:26 UTC (rev 264394)
@@ -26,6 +26,7 @@
#pragma once
#include <libsoup/soup.h>
+#include <wtf/RunLoop.h>
#include <wtf/glib/GRefPtr.h>
namespace IPC {
@@ -52,6 +53,7 @@
void didConnect(GRefPtr<SoupWebsocketConnection>&&);
void didFail(const String&);
void didClose(unsigned short code, const String& reason);
+ void delayFailTimerFired();
String acceptedExtensions() const;
@@ -65,6 +67,8 @@
GRefPtr<GCancellable> m_cancellable;
bool m_receivedDidFail { false };
bool m_receivedDidClose { false };
+ String m_delayErrorMessage;
+ RunLoop::Timer<WebSocketTask> m_delayFailTimer;
};
} // namespace WebKit