GHSA-8h6x-h86x-75wh: High severity go/github.com/emiago/sipgo vulnerability
Summary
The WebSocket transport allocates a buffer from the frame payload length before validating its size, which can lead to an unauthenticated DoS.
Details
WSConnection.Read allocates a buffer from the declared WebSocket frame length before reading the payload (https://github.com/emiago/sipgo/blob/v1.4.0/sip/transportws.go#L400):
go data := make([]byte, header.Length) // header.Length is client-controlled, up to 2^63-1 (int64)
- NextFrame() reads only the frame header and never checks the length: wsutil.NewReader is created with no MaxFrameSize (0 = unlimited). ParseMaxMessageLength applies only downstream, not here. - A value above the max slice size (e.g. 2^63-1) panics make. sipgo does not recover from this panic, so it crashes the whole server process.
PoC
Tested on emiago/sipgo v1.4.0 (latest).
After a normal WebSocket handshake, send one masked text frame consisting of the header only (no payload), declaring a huge length. The allocation runs as soon as the header is read.
0x81 FIN + text opcode 0xFF MASK bit + length marker 127 (8-byte length follows) 0x7F FF FF FF FF FF FF FF declared length = 2^63-1 -> make panics (crash) <4-byte masking key> (no payload)
This crashes the server process:
panic: runtime error: makeslice: len out of range
goroutine 23 [running]: github.com/emiago/sipgo/sip.(WSConnection).Read(...) /path/to/pkg/mod/github.com/emiago/sipgo@v1.4.0/sip/transportws.go:400 +0x2df github.com/emiago/sipgo/sip.(TransportWS).readConnection(...) /path/to/pkg/mod/github.com/emiago/sipgo@v1.4.0/sip/transportws.go:194 +0x266 created by github.com/emiago/sipgo/sip.(TransportWS).initConnection in goroutine 21 /path/to/pkg/mod/github.com/emiago/sipgo@v1.4.0/sip/transportws.go:167 +0x268
Suggested Fix
Set MaxFrameSize on the wsutil.NewReader.
Impact
Unauthenticated DoS. Any service using sipgo with a WS/WSS transport can be crashed by a single frame (panic), or forced to run out of memory.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
go/github.com/emiago/sipgoto a version that resolves this vulnerability.Fixed in 1.4.3 - Configuration
Set MaxFrameSize on wsutil.NewReader to a finite maximum so frame payload lengths are bounded before allocation.
sipgo WebSocket transport (wsutil.NewReader) MaxFrameSize = finite maximum; not 0 (unlimited)
Event History
Frequently Asked Questions
Who can trigger the denial of service?
Any unauthenticated client that can complete a normal WebSocket handshake with a SIPGo service using the affected WebSocket transport can trigger it. No credentials or user interaction are required.
What does exploitation require?
The attacker sends a masked WebSocket text-frame header declaring an extremely large payload length, without needing to send the payload itself. The server allocates based on that client-controlled length as soon as it reads the header, and an oversized value can panic the process.
Are size limits elsewhere in the application sufficient protection?
No. The downstream ParseMaxMessageLength setting does not protect this allocation, because the frame length is used before that validation; the WebSocket reader has no MaxFrameSize configured.
How can I tell whether a deployment is affected?
The issue was tested in SIPGo v1.4.0. Affected code creates a byte slice directly from the WebSocket header length in WSConnection.Read without first enforcing a frame-size limit or recovering from the resulting panic.
What should be done if an update cannot be applied immediately?
Restrict access to the WebSocket endpoint to trusted clients or place it behind a proxy or gateway that enforces a WebSocket frame-size limit. This reduces exposure to unauthenticated clients sending oversized frame headers.