Skip to content

Commit 1f512fc

Browse files
committed
Handle invalid close frames
Send protocol error if close code or payload are invalid. Fixes Autobahn tests 7.5.1, 7.9.*.
1 parent a724ba4 commit 1f512fc

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

conn.go

+32
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"net"
1515
"strconv"
1616
"time"
17+
"unicode/utf8"
1718
)
1819

1920
const (
@@ -43,6 +44,8 @@ const (
4344
CloseMessageTooBig = 1009
4445
CloseMandatoryExtension = 1010
4546
CloseInternalServerErr = 1011
47+
CloseServiceRestart = 1012
48+
CloseTryAgainLater = 1013
4649
CloseTLSHandshake = 1015
4750
)
4851

@@ -184,6 +187,29 @@ func isData(frameType int) bool {
184187
return frameType == TextMessage || frameType == BinaryMessage
185188
}
186189

190+
var validReceivedCloseCodes = map[int]bool{
191+
// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
192+
193+
CloseNormalClosure: true,
194+
CloseGoingAway: true,
195+
CloseProtocolError: true,
196+
CloseUnsupportedData: true,
197+
CloseNoStatusReceived: false,
198+
CloseAbnormalClosure: false,
199+
CloseInvalidFramePayloadData: true,
200+
ClosePolicyViolation: true,
201+
CloseMessageTooBig: true,
202+
CloseMandatoryExtension: true,
203+
CloseInternalServerErr: true,
204+
CloseServiceRestart: true,
205+
CloseTryAgainLater: true,
206+
CloseTLSHandshake: false,
207+
}
208+
209+
func isValidReceivedCloseCode(code int) bool {
210+
return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
211+
}
212+
187213
func maskBytes(key [4]byte, pos int, b []byte) int {
188214
for i := range b {
189215
b[i] ^= key[pos&3]
@@ -747,7 +773,13 @@ func (c *Conn) advanceFrame() (int, error) {
747773
if len(payload) >= 2 {
748774
echoMessage = payload[:2]
749775
closeCode = int(binary.BigEndian.Uint16(payload))
776+
if !isValidReceivedCloseCode(closeCode) {
777+
return noFrame, c.handleProtocolError("invalid close code")
778+
}
750779
closeText = string(payload[2:])
780+
if !utf8.ValidString(closeText) {
781+
return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
782+
}
751783
}
752784
c.WriteControl(CloseMessage, echoMessage, time.Now().Add(writeWait))
753785
return noFrame, &CloseError{Code: closeCode, Text: closeText}

0 commit comments

Comments
 (0)