Skip to content

Commit

Permalink
Handle invalid close frames
Browse files Browse the repository at this point in the history
Send protocol error if close code or payload are invalid.

Fixes Autobahn tests 7.5.1, 7.9.*.
  • Loading branch information
garyburd committed Apr 28, 2016
1 parent a724ba4 commit 1f512fc
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"net"
"strconv"
"time"
"unicode/utf8"
)

const (
Expand Down Expand Up @@ -43,6 +44,8 @@ const (
CloseMessageTooBig = 1009
CloseMandatoryExtension = 1010
CloseInternalServerErr = 1011
CloseServiceRestart = 1012
CloseTryAgainLater = 1013
CloseTLSHandshake = 1015
)

Expand Down Expand Up @@ -184,6 +187,29 @@ func isData(frameType int) bool {
return frameType == TextMessage || frameType == BinaryMessage
}

var validReceivedCloseCodes = map[int]bool{
// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number

CloseNormalClosure: true,
CloseGoingAway: true,
CloseProtocolError: true,
CloseUnsupportedData: true,
CloseNoStatusReceived: false,
CloseAbnormalClosure: false,
CloseInvalidFramePayloadData: true,
ClosePolicyViolation: true,
CloseMessageTooBig: true,
CloseMandatoryExtension: true,
CloseInternalServerErr: true,
CloseServiceRestart: true,
CloseTryAgainLater: true,
CloseTLSHandshake: false,
}

func isValidReceivedCloseCode(code int) bool {
return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
}

func maskBytes(key [4]byte, pos int, b []byte) int {
for i := range b {
b[i] ^= key[pos&3]
Expand Down Expand Up @@ -747,7 +773,13 @@ func (c *Conn) advanceFrame() (int, error) {
if len(payload) >= 2 {
echoMessage = payload[:2]
closeCode = int(binary.BigEndian.Uint16(payload))
if !isValidReceivedCloseCode(closeCode) {
return noFrame, c.handleProtocolError("invalid close code")
}
closeText = string(payload[2:])
if !utf8.ValidString(closeText) {
return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
}
}
c.WriteControl(CloseMessage, echoMessage, time.Now().Add(writeWait))
return noFrame, &CloseError{Code: closeCode, Text: closeText}
Expand Down

0 comments on commit 1f512fc

Please sign in to comment.