ratchetphp / Ratchet

Asynchronous WebSocket server
http://socketo.me
MIT License
6.25k stars 728 forks source link

Security issue: Long messages blocks all other communications! #461

Open David-x100 opened 7 years ago

David-x100 commented 7 years ago

I was writing my own WebSocket server using stream_* functions and pthreads. Then I asked myself: There is the excellent Ratchet, why reinvent the wheel?!

So as Ratchet is not threaded by pthreads and is async, I decided to check it against hackers attacks: What if a hacker sends a very long message?!

  1. First I run the Ratchet example server.
  2. Then I successfully connected to it as a good client from: http://www.websocket.org/echo.html
  3. At the end I opened following html file in Google Chrome to simulate a bad guy who wants to break our app, so sends a 20mb message to the server (change the ip:port in line 5 if you want to execute this):
<!DOCTYPE html>
  <meta charset="utf-8" />
  <title>WebSocket Test</title>
  <script language="javascript" type="text/javascript">

  var wsUri = "ws://127.0.0.1:9999/";
  var output;

  function init()
  {
    output = document.getElementById("output");
    testWebSocket();
  }

  function testWebSocket()
  {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function onOpen(evt)
  {
    message = 'x';
    writeToScreen("CONNECTED");
    doSend(message.repeat(1024*1024*20));
  }

  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  function onMessage(evt)
  {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }

  function onError(evt)
  {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }

  function doSend(message)
  {
    writeToScreen("SENT: " + (message.length > 1000 ? message.substring(0, 997) + '... (total size: ' + (message.length/1024/1024) + ' MB)': message));
    websocket.send(message);
  }

  function writeToScreen(message)
  {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }

  window.addEventListener("load", init, false);

  </script>

  <h2>WebSocket Test</h2>

  <div id="output"></div>

note: this code is modified version you can find from: http://www.websocket.org/echo.html

Boom! The good guy(s) can't send/receive messages anymore until the bad guy sends the very long message.

Is there a way to fix this issue of this great library? Am I doing something wrong?

mbonneau commented 5 years ago

Max message size should be implemented to prevent this.

@cboden Any thoughts?

vladiulianbogdan commented 4 years ago

Any update on this?

christiangarsia commented 4 years ago

This seems like a big issue when running this in a production environment. Any progress on a 'max message size' option?