Changeset 187556 in webkit


Ignore:
Timestamp:
Jul 29, 2015 2:08:30 PM (9 years ago)
Author:
beidson@apple.com
Message:

Crash calling webSocket.close() from onError handler for blocked web socket.
<rdar://problem/21771620> and https://bugs.webkit.org/show_bug.cgi?id=147411

Reviewed by Tim Horton.

Source/WebCore:

Tests: http/tests/security/mixedContent/websocket/insecure-websocket-in-iframe.html

http/tests/security/mixedContent/websocket/insecure-websocket-in-main-frame.html

This was introduced with http://trac.webkit.org/changeset/185848

  • Modules/websockets/WebSocket.cpp:

(WebCore::WebSocket::connect): When blocked because of mixedContent, call dispatchOrQueueErrorEvent().
(WebCore::WebSocket::didReceiveMessageError): Use dispatchOrQueueErrorEvent() instead.
(WebCore::WebSocket::dispatchOrQueueErrorEvent): Dispatch the error event, but don't dispatch one twice!

  • Modules/websockets/WebSocket.h:
  • Modules/websockets/WebSocketChannel.cpp:

(WebCore::WebSocketChannel::fail): Null-check m_handshake before creating a console message from it.

LayoutTests:

  • http/tests/security/mixedContent/resources/frame-with-insecure-websocket.html: Add a call to webSocket.close() inside the onError handler.
  • http/tests/security/mixedContent/websocket/insecure-websocket-in-iframe-expected.txt:
  • http/tests/security/mixedContent/websocket/insecure-websocket-in-main-frame-expected.txt:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r187552 r187556  
     12015-07-29  Brady Eidson  <beidson@apple.com>
     2
     3        Crash calling webSocket.close() from onError handler for blocked web socket.
     4        <rdar://problem/21771620> and https://bugs.webkit.org/show_bug.cgi?id=147411
     5
     6        Reviewed by Tim Horton.
     7
     8        * http/tests/security/mixedContent/resources/frame-with-insecure-websocket.html: Add a call to webSocket.close() inside the onError handler.
     9        * http/tests/security/mixedContent/websocket/insecure-websocket-in-iframe-expected.txt:
     10        * http/tests/security/mixedContent/websocket/insecure-websocket-in-main-frame-expected.txt:
     11
    1122015-07-19  Matt Rajca  <mrajca@apple.com>
    213
  • trunk/LayoutTests/http/tests/security/mixedContent/resources/frame-with-insecure-websocket.html

    r185848 r187556  
    22<script>
    33window.jsTestIsAsync = true;
     4
     5var ws;
    46
    57function onSocketOpened() {
     
    1012function onSocketError() {
    1113    alert("WebSocket connection failed.");
     14    ws.close();
    1215    finishJSTest();
    1316}
     
    1922
    2023try {
    21     var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/echo");
     24    ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/echo");
    2225    ws.onopen = onSocketOpened;
    2326    ws.onerror = onSocketError;
  • trunk/LayoutTests/http/tests/security/mixedContent/websocket/insecure-websocket-in-iframe-expected.txt

    r185848 r187556  
    1 CONSOLE MESSAGE: line 21: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/frame-with-insecure-websocket.html was not allowed to run insecure content from ws://127.0.0.1:8880/websocket/tests/hybi/echo.
     1CONSOLE MESSAGE: line 24: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/frame-with-insecure-websocket.html was not allowed to run insecure content from ws://127.0.0.1:8880/websocket/tests/hybi/echo.
    22
    33ALERT: WebSocket connection failed.
     4CONSOLE MESSAGE: line 14: WebSocket connection failed: WebSocket is closed before the connection is established.
    45This test loads an iframe that creates an insecure WebSocket connection. We should block the connection and trigger a mixed content callback because the main frame is HTTPS, but the data sent over the socket could be recorded or controlled by an attacker.
    56
  • trunk/LayoutTests/http/tests/security/mixedContent/websocket/insecure-websocket-in-main-frame-expected.txt

    r185848 r187556  
    1 CONSOLE MESSAGE: line 21: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/frame-with-insecure-websocket.html was not allowed to run insecure content from ws://127.0.0.1:8880/websocket/tests/hybi/echo.
     1CONSOLE MESSAGE: line 24: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/frame-with-insecure-websocket.html was not allowed to run insecure content from ws://127.0.0.1:8880/websocket/tests/hybi/echo.
    22
    33ALERT: WebSocket connection failed.
     4CONSOLE MESSAGE: line 14: WebSocket connection failed: WebSocket is closed before the connection is established.
    45This test opens a window that connects to an insecure ws:// WebSocket. We should block the connection and trigger a mixed content callback because the main frame is HTTPS, but the data sent over the socket could be recorded or controlled by an attacker.
  • trunk/Source/WebCore/ChangeLog

    r187546 r187556  
     12015-07-29  Brady Eidson  <beidson@apple.com>
     2
     3        Crash calling webSocket.close() from onError handler for blocked web socket.
     4        <rdar://problem/21771620> and https://bugs.webkit.org/show_bug.cgi?id=147411
     5
     6        Reviewed by Tim Horton.
     7
     8        Tests: http/tests/security/mixedContent/websocket/insecure-websocket-in-iframe.html
     9               http/tests/security/mixedContent/websocket/insecure-websocket-in-main-frame.html
     10
     11        This was introduced with http://trac.webkit.org/changeset/185848
     12
     13        * Modules/websockets/WebSocket.cpp:
     14        (WebCore::WebSocket::connect): When blocked because of mixedContent, call dispatchOrQueueErrorEvent().
     15        (WebCore::WebSocket::didReceiveMessageError): Use dispatchOrQueueErrorEvent() instead.
     16        (WebCore::WebSocket::dispatchOrQueueErrorEvent): Dispatch the error event, but don't dispatch one twice!
     17        * Modules/websockets/WebSocket.h:
     18
     19        * Modules/websockets/WebSocketChannel.cpp:
     20        (WebCore::WebSocketChannel::fail): Null-check m_handshake before creating a console message from it.
     21
    1222015-07-29  Michael Catanzaro  <mcatanzaro@igalia.com>
    223
  • trunk/Source/WebCore/Modules/websockets/WebSocket.cpp

    r186388 r187556  
    285285            // Balanced by the call to ActiveDOMObject::unsetPendingActivity() in WebSocket::stop().
    286286            ActiveDOMObject::setPendingActivity(this);
     287
    287288            // We must block this connection. Instead of throwing an exception, we indicate this
    288289            // using the error event. But since this code executes as part of the WebSocket's
     
    290291            // event; otherwise, users can't connect to the event.
    291292            RunLoop::main().dispatch([this]() {
    292                 dispatchEvent(Event::create(eventNames().errorEvent, false, false));
     293                dispatchOrQueueErrorEvent();
    293294                stop();
    294295            });
     
    588589    m_state = CLOSED;
    589590    ASSERT(scriptExecutionContext());
    590     dispatchOrQueueEvent(Event::create(eventNames().errorEvent, false, false));
     591    dispatchOrQueueErrorEvent();
    591592}
    592593
     
    639640}
    640641
     642void WebSocket::dispatchOrQueueErrorEvent()
     643{
     644    if (m_dispatchedErrorEvent)
     645        return;
     646
     647    m_dispatchedErrorEvent = true;
     648    dispatchOrQueueEvent(Event::create(eventNames().errorEvent, false, false));
     649}
     650
    641651void WebSocket::dispatchOrQueueEvent(Ref<Event>&& event)
    642652{
  • trunk/Source/WebCore/Modules/websockets/WebSocket.h

    r184709 r187556  
    111111
    112112    void resumeTimerFired();
     113    void dispatchOrQueueErrorEvent();
    113114    void dispatchOrQueueEvent(Ref<Event>&&);
    114115
     
    144145    bool m_shouldDelayEventFiring { false };
    145146    Deque<Ref<Event>> m_pendingEvents;
     147    bool m_dispatchedErrorEvent { false };
    146148};
    147149
  • trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp

    r186476 r187556  
    202202    if (m_document) {
    203203        InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_identifier, reason);
    204         m_document->addConsoleMessage(MessageSource::Network, MessageLevel::Error, "WebSocket connection to '" + m_handshake->url().stringCenterEllipsizedToLength() + "' failed: " + reason);
     204
     205        String consoleMessage;
     206        if (m_handshake)
     207            consoleMessage = makeString("WebSocket connection to '", m_handshake->url().stringCenterEllipsizedToLength(), "' failed: ", reason);
     208        else
     209            consoleMessage = makeString("WebSocket connection failed: ", reason);
     210
     211        m_document->addConsoleMessage(MessageSource::Network, MessageLevel::Error, consoleMessage);
    205212    }
    206213
     
    219226        m_handle->disconnect(); // Will call didClose().
    220227
    221     ASSERT(m_closed);
     228    // We should be closed by now, but if we never got a handshake then we never even opened.
     229    ASSERT(m_closed || !m_handshake);
    222230}
    223231
Note: See TracChangeset for help on using the changeset viewer.