DoS via WebSocket frame with oversize 64-bit payload length field (Int trap in WebSocketFrameDecoder)
Summary
WebSocketFrameDecoder used Swift's trapping Int(_:) initializer to convert the 8-byte extended payload length field of a WebSocket frame (RFC 6455 §5.2). Any 64-bit length value with the most-significant bit set (≥ 0x8000_0000_0000_0000) caused a fatal runtime trap and terminated the process. The trap fired before maxFrameSize validation, so no configuration could mitigate it, and ByteToMessageDecoder cannot catch a runtime trap.
Impact
An unauthenticated remote peer can crash any NIOWebSocket-based server (including Vapor and Hummingbird) with a single 11-byte frame sent after a completed WebSocket handshake, dropping all active connections until the process restarts.
Proof of Concept
`
81 7F 80 00 00 00 00 00 00 00 00
`
Fix
Fixed in #3603: the decoder now uses Int(exactly:) and throws NIOWebSocketError.invalidFrameLength for out-of-range lengths instead of trapping.
Found & Fixed by @g0w6y
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| swift-nio Product | < 2.101.0 | 2.101.0 |
Details and references
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-190