Regex backtracking Denial of Service in Sec-Websocket-Protocol Header

ReDoS in Sec-Websocket-Protocol header

Package Information

  • Package: ws (npm)

  • Affected versions:

    • >= 5.0.0 < 5.2.3

    • >= 6.0.0 < 6.2.2

    • >= 7.0.0 < 7.4.6

  • Patched versions:

    • 5.2.3

    • 6.2.2

    • 7.4.6

Description

ws is an open-source WebSocket client and server library for Node.js. A specially crafted value of the Sec-Websocket-Protocol header can be used to significantly slow down a ws server.

Impact

A specially crafted value of the Sec-Websocket-Protocol header can be used to significantly slow down a ws server, leading to a Denial of Service (DoS).

How to Perform the Attack

Example Scenario: Example Site

Let's consider an example site using a ws WebSocket server at https://example.com/socket.

  1. Navigate to the WebSocket URL:

    • wss://example.com/socket

  2. Craft the malicious payload:

    • The payload will consist of a large number of spaces within the Sec-Websocket-Protocol header. This is designed to exploit regex backtracking in the ws package.

  3. Example Payload:

    • "Sec-WebSocket-Protocol: b${' '.repeat(32000)}x"

  4. Using the payload in a WebSocket request:

    • You can use the following JavaScript code to create a WebSocket connection with the crafted Sec-Websocket-Protocol header.

  5. Explanation of the script:

    • The script creates a WebSocket connection to the example site with a malicious Sec-Websocket-Protocol header.

    • The payload contains a large number of spaces, which will be processed by the ws server.

  6. Observe the server's response time:

    • Monitor the server's response time and resource usage. The server should exhibit significant delays or high CPU usage due to the regex backtracking issue.

Detailed Proof of Concept (PoC)

Use the following script to measure the impact of different payload lengths:

Patches

The vulnerability was fixed in:

In vulnerable versions of ws, the issue can be mitigated by reducing the maximum allowed length of the request headers using the --max-http-header-size=size and/or the maxHeaderSize options.

Last updated