rfc-6455

The WebSocket Protocol

I. Fette, A. Melnikov
date2011-12 streamIETF areaart wghybi statusPROPOSED STANDARD pages71 canonicalhttps://www.rfc-editor.org/rfc/rfc6455 doi10.17487/RFC6455 errataview
The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or <iframe>s and long polling). [STANDARDS-TRACK]

updated by

Extracted elements (30)

design-rationale §10.3

Client-to-server masking was introduced to prevent cache-poisoning attacks where a malicious script causes a browser to send crafted bytes through an intermediary proxy. By requiring an unpredictable masking key, the attacker cannot control the exact byte sequence on the wire, preventing the intermediary from misinterpreting the payload as an HTTP response.

websocket, security

design-rationale §1.5

The protocol uses minimal framing — only enough to distinguish text from binary frames and to support fragmentation — because metadata is expected to be layered by the application (as HTTP layers on TCP). The design goal was to be as close to raw TCP as is safe given web infrastructure constraints.

websocket

interoperability-note §1.3

The WebSocket opening handshake is a valid HTTP/1.1 Upgrade request, allowing WebSocket clients and HTTP clients to share port 80 (ws) or 443 (wss) on the same server. HTTP proxies that do not support WebSocket will receive a CONNECT-tunneled connection or will proxy the upgrade, depending on configuration.

websocket, http

normative-requirement §5.1 MUST

A client MUST mask all frames sent to the server. The server MUST close the connection upon receiving an unmasked frame and MUST NOT mask any frames it sends to the client. A client MUST close the connection if it detects a masked frame from the server.

websocket, security

normative-requirement §5.5 MUST

All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented. Currently defined control opcodes are Close (0x8), Ping (0x9), and Pong (0xA).

websocket

normative-requirement §8.1 MUST

If at any time an endpoint encounters data destined for the UTF-8 decoder that does not conform to the UTF-8 specification (RFC 3629), the endpoint MUST fail the WebSocket connection. Clients MUST NOT show Close frame reason text to end users as it is not guaranteed to be human-readable.

websocket

normative-requirement §4.1 MUST

If the wss: URI scheme is used, the client MUST perform a TLS handshake before sending any WebSocket handshake data and MUST use the Server Name Indication (SNI) extension as specified in RFC 6066.

websocket, tls

normative-requirement §5.4 MUST

Message fragments MUST be delivered in the order sent, and fragments of one message MUST NOT be interleaved with fragments of another message unless an extension explicitly permits it. Clients and servers MUST support receiving both fragmented and unfragmented messages.

websocket

normative-requirement §5.2 MUST

RSV1, RSV2, and RSV3 bits MUST be 0 unless an extension negotiated during the handshake defines meanings for non-zero values. If a nonzero value is received and no negotiated extension defines it, the receiving endpoint MUST fail the WebSocket connection.

websocket

normative-requirement §4.1 MUST

The client MUST validate the server's response: status code must be 101, Upgrade header must contain 'websocket', Connection must contain 'Upgrade', and Sec-WebSocket-Accept must match the expected base64-SHA-1 value. Any mismatch requires failing the WebSocket connection.

websocket, http

normative-requirement §4.1 MUST

The client's opening handshake MUST be a valid HTTP/1.1 GET request containing Host, Upgrade: websocket, Connection: Upgrade, Sec-WebSocket-Key (base64-encoded 16-byte nonce), and Sec-WebSocket-Version: 13 header fields.

websocket, http

normative-requirement §5.3 MUST

The masking key MUST be derived from a strong source of entropy (per RFC 4086) and MUST NOT be predictable from prior frame masking keys, to prevent malicious applications from selecting the bytes that appear on the wire.

websocket, security

normative-requirement §4.1 MUST

The Sec-WebSocket-Key header field MUST contain a randomly selected 16-byte nonce that has been base64-encoded, and the nonce MUST be selected randomly for each connection.

websocket, security

normative-requirement §4.1 MUST

There MUST be no more than one WebSocket connection in a CONNECTING state to the same remote host (IP address) and port at any time; the client MUST serialize simultaneous connection attempts to prevent denial-of-service conditions.

websocket, security

normative-requirement §4.4 MUST

When a server receives a Sec-WebSocket-Version value it does not support, it MUST abort the handshake with an appropriate HTTP error (e.g., 426 Upgrade Required) and MUST include a Sec-WebSocket-Version header field listing all versions it is willing to use.

websocket, http

protocol-element §5.4

A fragmented message consists of a first frame with FIN=0 and a non-zero opcode, followed by zero or more continuation frames (opcode=0x0, FIN=0), terminated by a continuation frame with FIN=1. All fragments of a message share the type set by the first fragment's opcode.

websocket

protocol-element §1.9

Subprotocol negotiation uses Sec-WebSocket-Protocol: the client lists acceptable subprotocols in preference order; the server selects at most one and echoes it. If the server returns a subprotocol not offered by the client, the client MUST fail the connection. Subprotocol names SHOULD use reverse-domain naming (e.g., 'chat.example.com') to avoid collisions.

websocket

protocol-element §5.5.1

The Close frame (opcode 0x8) optionally carries a 2-byte unsigned integer status code (network byte order) followed by a UTF-8 reason string. Upon receiving a Close frame without having sent one, an endpoint MUST send a Close frame in response, then both endpoints MUST close the underlying TCP connection.

websocket

protocol-element §4.2.2

The server constructs Sec-WebSocket-Accept by concatenating the Sec-WebSocket-Key string value with the fixed GUID '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', computing the SHA-1 hash (20 bytes), and base64-encoding the result. This proves the server received the WebSocket-specific handshake.

websocket, security, crypto

protocol-element §5.5.2

Upon receiving a Ping frame (opcode 0x9), an endpoint MUST send a Pong frame (opcode 0xA) in response unless it has already sent a Close frame. A Pong sent in response MUST carry the identical application data as the triggering Ping. An endpoint MAY send unsolicited Pong frames.

websocket

registry §11.1

IANA registered the 'ws' (default port 80) and 'wss' (default port 443) URI schemes, the 'WebSocket' HTTP Upgrade keyword, and five new HTTP header fields: Sec-WebSocket-Key, Sec-WebSocket-Extensions, Sec-WebSocket-Accept, Sec-WebSocket-Protocol, and Sec-WebSocket-Version.

websocket, registry, http

registry §11.4

This document creates six new IANA registries: WebSocket Extension Name Registry (Specification Required), WebSocket Subprotocol Name Registry (First Come First Served), WebSocket Version Number Registry, WebSocket Close Code Number Registry, WebSocket Opcode Registry, and WebSocket Framing Header Bits Registry.

websocket, registry

security-consideration §10.4

Implementations should impose limits on frame and message sizes, header field lengths, and connection counts to mitigate resource exhaustion. Servers can reduce load during attacks by delaying closure to reduce client reconnection rates.

websocket, security

security-consideration §10.2

Servers SHOULD validate the Origin header to prevent unauthorized cross-origin use by browser scripts. Non-browser clients can provide any arbitrary Origin value, so origin validation only provides meaningful protection for browser-initiated connections.

websocket, security

security-consideration §10.8

SHA-1 is used in the opening handshake to compute Sec-WebSocket-Accept for proof-of-receipt only, not for cryptographic security. Known weaknesses of SHA-1 (collision resistance) do not apply to this non-cryptographic use, as the purpose is merely to confirm the server read the WebSocket-specific handshake.

websocket, security, crypto

security-consideration §10.3

The strict handshake (Sec-WebSocket-Key/Accept exchange with a fixed GUID) is designed to prevent cross-protocol attacks: pre-existing protocols like SMTP and HTTP cannot accidentally complete a WebSocket handshake, and XMLHttpRequest cannot forge Sec-* headers from a browser context.

websocket, security

state-machine §4.1

A WebSocket connection transitions through states: CONNECTING (initial, during handshake), OPEN (after successful handshake; data exchange permitted), CLOSING (after a Close frame has been sent or received), and CLOSED (after underlying TCP connection is closed). The 'Fail the WebSocket Connection' procedure forces transition to CLOSED.

websocket

wire-format §5.3

Masking is performed by XOR: transformed-octet-i = original-octet-i XOR masking-key-octet[i MOD 4], where the masking key is a 32-bit (4-byte) value carried in the frame header. The same algorithm applies for masking and unmasking.

websocket, security

wire-format §5.2

Payload length uses minimal variable-length encoding: 0–125 in the 7-bit field is the direct length; 126 means the following 2 bytes (16-bit unsigned) carry the length; 127 means the following 8 bytes (64-bit unsigned, MSB MUST be 0) carry the length. Lengths MUST use the minimum number of bytes.

websocket

wire-format §5.2

The base WebSocket frame header consists of: FIN (1 bit), RSV1-3 (1 bit each), opcode (4 bits), MASK (1 bit), payload length (7 bits, extended to 7+16 or 7+64 bits when the 7-bit value is 126 or 127), an optional 32-bit masking key (present when MASK=1), and variable-length payload data.

websocket