RFC Errata


Errata Search

 
Source of RFC  
Summary Table Full Records

Found 9 records.

Status: Verified (3)

RFC 6455, "The WebSocket Protocol", December 2011

Note: This RFC has been updated by RFC 7936, RFC 8307, RFC 8441

Source of RFC: hybi (app)

Errata ID: 3150
Status: Verified
Type: Technical
Publication Format(s) : TEXT

Reported By: Robert Munyer
Date Reported: 2012-03-07
Verifier Name: Peter Saint-Andre
Date Verified: 2012-03-22

Section 4.1 says:

AQIDBAUGBwgJCgsMDQ4PEC==

It should say:

AQIDBAUGBwgJCgsMDQ4PEA==

Notes:

The "test vector" for Sec-WebSocket-Key encoding, provided in RFC 6455 section 4.1, is wrong. It was processed by a base 64 encoder that was "improperly implemented" as mentioned in RFC 4648 section 3.5. Pad bits were not set to zero, which is a "MUST" requirement in RFC 4648, and was also required by many other RFCs, going back to RFC 989 in the 1980s. In the string "AQIDBAUGBwgJCgsMDQ4PEC==", the final C should be changed to A.

In a Sec-WebSocket-Key header sent by a properly implemented client, the last letter will always be A, Q, g or w.

Errata ID: 3433
Status: Verified
Type: Technical
Publication Format(s) : TEXT

Reported By: Eric Lawrence
Date Reported: 2012-12-20
Verifier Name: Barry Leiba
Date Verified: 2012-12-22

Section 11.3.2 says:

However, the |Sec-WebSocket-Extensions| header field MUST NOT appear
more than once in an HTTP response.

It should say:

The |Sec-WebSocket-Extensions| header field MAY appear multiple 
times in an HTTP response (which is logically the same as a single
|Sec-WebSocket-Extensions| header field that contains all values).

Notes:

Section 4.2.2 Step 5 subpart 6 (top of page 25) clearly explains that this header field may appear multiple times in the server's response: "If multiple extensions are to be used, they can all be listed in a single |Sec-WebSocket-Extensions| header field or split between multiple instances of the |Sec-WebSocket-Extensions| header field. This completes the server's handshake..."

Errata ID: 3473
Status: Verified
Type: Editorial
Publication Format(s) : TEXT

Reported By: Adam Rice
Date Reported: 2013-01-31
Verifier Name: Barry Leiba
Date Verified: 2013-02-18

Section 4.1 says:

   2.  If the client already has a WebSocket connection to the remote
       host (IP address) identified by /host/ and port /port/ pair, even
       if the remote host is known by another name, the client MUST wait
       until that connection has been established or for that connection
       to have failed.  There MUST be no more than one connection in a
       CONNECTING state.  If multiple connections to the same IP address
       are attempted simultaneously, the client MUST serialize them so
       that there is no more than one connection at a time running
       through the following steps.

It should say:

   2.  If the client already has a WebSocket connection to the same IP
       address and port pair, even if the remote host is known by another
       name, the client MUST wait until that connection has been established
       or for that connection to have failed.  There MUST be no more than
       one connection in the CONNECTING state for any IP address and port
       pair.  If multiple connections to the same IP address and port pair
       are attempted simultaneously, the client MUST serialize them so that
       there is no more than one connection at a time running through the
       following steps.

Notes:

The original wording makes it ambiguous whether distinct ports on the same host are considered distinct for throttling purposes. The first sentence implies that the throttling should be applied per (host,port) pair, whereas the final sentence implies it is only based on IP address.

Implementations of both interpretations appear to exist in the wild.

I propose disambiguating in favour of the (host,port) interpretation, because the host-only interpretation allows for a potential denial-of-service attack targeted against hosts which drop packets to unused ports.

For example, an attacker from a different origin can create several hundred WebSockets to "wss://google.com:81/". Each one will attempt to connect in serial, and take tens of seconds to time out.

If the user then attempts to use an application which legitimately uses a WebSocket to "wss://google.com:443/", then due to the throttling to google.com it will not be able to connect until all of the attacker's connections have timed out.

The user will perceive that the legitimate application is malfunctioning, since there is no visible sign that they are being attacked. From the server end, the attack is only apparent in the firewall logs. The actual rate of SYN packets dropped will be small and unlikely to trigger an alert.

On the other hand, with the (host,port) interpretation, connections to google.com:81 do not block connections to google.com:443, and this attack is completely ineffective.

=== Verifier Notes ===

The subsequent paragraph already indicates what must be done in the case where the IP address cannot be determined, so this change should not create any difficulties in the case where the connection is tunnelled via an HTTP(S) or SOCKS5 proxy.

A separate concern has been raised that this section creates problems for WebSocket proxies and non-browser clients. That issue cannot be handled without changing the meaning of the text, so it would have to be dealt with in a document update.

Status: Reported (6)

RFC 6455, "The WebSocket Protocol", December 2011

Note: This RFC has been updated by RFC 7936, RFC 8307, RFC 8441

Source of RFC: hybi (app)

Errata ID: 4672
Status: Reported
Type: Technical
Publication Format(s) : TEXT

Reported By: Anton Dunaev
Date Reported: 2016-04-18

Section 5.6 says:

   Data frames (e.g., non-control frames) are identified by opcodes
   where the most significant bit of the opcode is 0.  Currently defined
   opcodes for data frames include 0x1 (Text), 0x2 (Binary).  Opcodes
   0x3-0x7 are reserved for further non-control frames yet to be
   defined.

   Data frames carry application-layer and/or extension-layer data.  The
   opcode determines the interpretation of the data:

   Text

      The "Payload data" is text data encoded as UTF-8.  Note that a
      particular text frame might include a partial UTF-8 sequence;
      however, the whole message MUST contain valid UTF-8.  Invalid
      UTF-8 in reassembled messages is handled as described in
      Section 8.1.

   Binary

      The "Payload data" is arbitrary binary data whose interpretation
      is solely up to the application layer.

It should say:

   Data frames (i.e., non-control frames) are identified by opcodes
   where the most significant bit of the opcode is 0.  Currently defined
   opcodes for data frames include 0x00 (Continuation), 0x1 (Text) and
   0x2 (Binary).  Opcodes 0x3-0x7 are reserved for further non-control
   frames yet to be defined.

   Data frames carry application-layer and/or extension-layer data.  The
   opcode determines the interpretation of the data:

   Text

      The "Payload data" is text data encoded as UTF-8.  Note that a
      particular text frame might include a partial UTF-8 sequence;
      however, the whole message MUST contain valid UTF-8.  Invalid
      UTF-8 in reassembled messages is handled as described in
      Section 8.1.

   Binary

      The "Payload data" is arbitrary binary data whose interpretation
      is solely up to the application layer.

   Continuation

      These frames MUST be always preceeded by either Text or Binary
      frame with FIN bit clear (See Section 5.2). The "Payload data"
      contains next fragment (See section 5.4) of the message whose
      transmission were opened by the latest Text or Binary frame and
      MUST be interpreted in the same way as the initial fragment of
      the message.

Notes:

For any other opcode defined frames are explicitly listed and described in either Section 5.5 or Section 5.6. But continuation frame is not.

Formally it matches definition of data frame (given in section 5.6) as the most significant bit of its opcode is 0. Logically it should be data frame too. But it is unclear whether there are two categories of frames (data and control) or the Continuation frame represents the third.

One could guess though that Continuation frame is a data frame from the content of the section 5.5.1 stating that "An endpoint MAY delay sending a Close frame until its current message is sent (for instance, if the majority of a fragmented message is already sent, an endpoint MAY send the remaining fragments before sending a Close frame)". This fragment clarifies that Close frame is sent after an endpoint finished message transmission. Thus such interpreation would be consistent with the Section 5.5.1 stating that "The application MUST NOT send any more data frames after sending a Close frame".

Errata ID: 4919
Status: Reported
Type: Technical
Publication Format(s) : TEXT

Reported By: Jefferson Carpenter
Date Reported: 2017-01-28

Section 7.4.1 says:

1001 indicates that an endpoint is "going away", such as a server
      going down or a browser having navigated away from a page.

It should say:

(unsure)

Notes:

This status code apparently covers two entirely different situations: a server going down, and a browser having navigated away. What is meant by "going away", why can't these be 2 different status codes? That info should be present in the RFC text.

Errata ID: 7608
Status: Reported
Type: Technical
Publication Format(s) : TEXT

Reported By: Esmond Pitt
Date Reported: 2023-08-19

Section 7.1.1 says:

The underlying TCP connection, in most normal cases, SHOULD be closed
   first by the server, so that it holds the TIME_WAIT state and not the
   client (as this would prevent it from re-opening the connection for 2
   maximum segment lifetimes (2MSL), while there is no corresponding
   server impact as a TIME_WAIT connection is immediately reopened upon
   a new SYN with a higher seq number).  

It should say:

The underlying TCP connection, in most normal cases, SHOULD be closed
   first by the server, so that the TIME_WAIT occurs at the
   client, not at the server.  

Notes:

1. There is no such thing as a 'TIME_WAIT connection'.
2. TCP connections are never reused.
3. It is better for the TIME_WAIT *port* states to accumulate at the clients rather than at the server, as this distributes them among the client base and avoids possible resource exhaustion at the server (NB *not* port exhaustion, as the server is only using one port).
4. The part about 'as this would prevent it [the client] from re-opening the connection' is only true if the client is using a fixed local port number, which never works anyway.
5. The part about ' a TIME_WAIT connection is immediately reopened upon
a new SYN with a higher seq number' is nonsense.

Errata ID: 6997
Status: Reported
Type: Technical
Publication Format(s) : TEXT

Reported By: Daniel Egger
Date Reported: 2022-06-17

Section 4.3, 9.1 says:

      extension-param = token [ "=" (token | quoted-string) ]
           ; When using the quoted-string syntax variant, the value
           ; after quoted-string unescaping MUST conform to the
           ; 'token' ABNF.

It should say:

      extension-param = token [ "=" (token | quoted-string) ]

Notes:

The text reads as if any quoted-string which was supplied as a value has to follow the same rules as a token. That precludes the use of any token separators inside a quoted-string which is the whole reason why quoted-string exists as explained in RFC 2616:

Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value (as defined in section
3.6).

Errata ID: 7262
Status: Reported
Type: Technical
Publication Format(s) : TEXT

Reported By: Demi Y
Date Reported: 2022-12-09

Section 5.5.1 says:

Following the 2-byte integer, the body MAY contain UTF-8-encoded data
with value /reason/, the interpretation of which is not defined by
this specification.  This data is not necessarily human readable but
may be useful for debugging or passing information relevant to the
script that opened the connection.  As the data is not guaranteed to
be human readable, clients MUST NOT show it to end users.

It should say:

> Following the 2-byte integer, the body MAY contain data which MUST
be UTF-8-encoded with value /reason/, the interpretation of which is
not defined by this specification.

> As the interpretation is not defined here, clients MAY show it to
end users.

----- OR -----

> Following the 2-byte integer, the body MAY contain arbitrary data,
the interpretation of which is not defined by this specification.

> As the interpretation is not defined here, clients MAY hide it
from end users.

Notes:

The RFC is unclear on whether or not close-frames can contain binary data for the /reason/.

In section 5.2, "Application data" is defined as "arbitrary".

Section 5.5.1 also says about the /reason/:
> This data is not necessarily human readable ...
> As the data is not guaranteed to be human readable ...

Ok, but what if it is?

As per RFC 2119, The "MUST NOT show it to end users" here is not a mere suggestion.
It implies some sort of inherent danger or contract breaking that would occur if the data were "shown" (undefined term), as if passing along UTF-8 text in a controlled manner could cause harm to their application.

Due to the "MUST NOT", the "MAY contain UTF-8-encoded data" here is ambiguous. It implies it could be something other than UTF-8, like binary data, which would be unsafe to blindly "show" to the "end user" (undefined term). There is no clear reason as to why it (emphatically) "MUST NOT" be shown to "end users".

Who is the client and who is the "end user"? This is the only occurrence of "end user" in the RFC. Is the "client" the browser, and the "end user" the developer trying to debug their application, but "MUST NOT" see close /reason/s? In practice, the close reason is of course exposed by browsers. But then is the end user the non-developer who triggers an unexpected error on the server, and has no way to report a bug since the server's error /reason/ MUST NOT be shown to them? Why MUSTN'T it be shown? Is it because it MAY contain binary data?

Clarification is needed on whether or not the /reason/ can contain arbitrary binary data. And the imperative restriction on what the undefined "end user" can be "shown" should be loosened.

Errata ID: 5288
Status: Reported
Type: Editorial
Publication Format(s) : TEXT

Reported By: champkeh
Date Reported: 2018-03-20

Section 5.2 says:

frame-payload-length-16 = %x0000-FFFF ; 16 bits in length

frame-payload-length-63 = %x0000000000000000-7FFFFFFFFFFFFFFF
                        ; 64 bits in length

frame-masking-key       = 4( %x00-FF )
                        ; present only if frame-masked is 1
                        ; 32 bits in length

It should say:

frame-payload-length-16 = %x0000-FFFF ; 16 bits in length

frame-payload-length-63 = %x0000000000000000-7FFFFFFFFFFFFFFF
                        ; 64 bits in length

frame-masking-key       = %x00000000-FFFFFFFF
                        ; present only if frame-masked is 1
                        ; 32 bits in length

Notes:

frame-masking-key is 32bits in length

Report New Errata



Advanced Search