Project

General

Profile

Actions

Bug #7285

open

Websocket compression mishandling

Added by Hans Vermeer 6 months ago. Updated 2 days ago.

Status:
In Review
Priority:
Normal
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

There are a number of problems with the decompression implementation of WebSockets. Firstly, in the example PCAP every individual transaction is comprised of a single frame, which fails (https://github.com/OISF/suricata/blob/089d2b1/rust/src/websocket/websocket.rs#L202) because the buffer is empty and the fin flag is set, therefore the path is never executed and for the same reason its not marked as compressed.

Now the other problem is with the LZ77 sliding window (https://datatracker.ietf.org/doc/html/rfc7692#section-7.2.2). In this case the Sec-WebSocket-Extensions negotiate a client_max_window_bits=15, but this is not followed in the decompression, resulting in the situations in the screenshot where blocks of data are missing (only after marking every frame as compressed).
Lastly, it doesn't seem like there is any handling on decompression limits with the DeflateDecoder, despite the default WEBSOCKET_MAX_PAYLOAD_SIZE of size 0xffff (which can be increased by users), 65kb is probably enough to have a decent deflate bomb (it seems the limit is ~1032 * 0xffff ~ 67mb).

A python example that handles the decompression properly:

import zlib

leader = "0000ffff" 
pkts = ["f2768db435304f4eb23435b54c4d4b33324c354e353649334e4a4a31b4303231484a4c360600", "0af17777f771b5354ab1304832324a4d49324e4c4b0600", "820a9a9ba59898a65aa4a6a4261a1ba40100"]
client_max_window_bits = 15
c = zlib.decompressobj(-client_max_window_bits)

for p in pkts:
    print(c.decompress(bytes.fromhex(p + leader)))


Files

example_websocket.pcap (2.82 KB) example_websocket.pcap pcap Hans Vermeer, 09/26/2024 06:30 PM
websocket_fail.png (28.1 KB) websocket_fail.png Hans Vermeer, 09/26/2024 06:39 PM
websocket_fail2.png (36.9 KB) websocket_fail2.png Hans Vermeer, 09/26/2024 06:40 PM
Actions #1

Updated by Philippe Antoine 26 days ago

  • Assignee changed from OISF Dev to Philippe Antoine
Actions #2

Updated by Philippe Antoine 5 days ago

  • Target version changed from TBD to 8.0.0-rc1
Actions #3

Updated by Philippe Antoine 4 days ago

  • Status changed from New to In Progress

I have a branch websocket-compression-7285-v1.1

Actions #4

Updated by Philippe Antoine 2 days ago

  • Status changed from In Progress to In Review
Actions

Also available in: Atom PDF