Subject: [Gen-art] Review of draft-ietf-hybi-thewebsocketprotocol-13

From: "Richard L. Barnes" <[email-masked]>
Date: Fri, 2 Sep 2011 16:30:04 -0400

Hey all,

I was selected for the Gen-ART review of draft-ietf-hybi-thewebsocketprotocol, and submitted a review during IETF LC:
<>
Since it's coming up for telechat, I thought I would give it a second look.  Comments on the diff are below.

--Richard

Section 2, "Implementations MAY impose implementation-specific limits..."
This paragraph has been removed in -13.  While the "MAY" doesn't specify a requirement, it seems like it would be helpful to implementers in light of the exhaustion/DoS possibilities presented by huge frames and fragmentation.  I would even argue that it should be a "SHOULD".

Section 5.4, "Unless specified otherwise by an extension, frames have no semantic meaning."
This caveat seems to invite breakage, especially since there are no extensions defined and no examples given of what sort of semantics might be attached.  (I'm guessing this has to do with 'deflate'?)  At the very least, it seems like there should be a requirement that when an intermediary sees an extension that it doesn't understand, it MUST NOT fragment or coalesce frames.  

Section 5.4, "Implementation Note: in absence of any extension..."
Same considerations apply here.  This note seems to encourage behavior that will cause incompatibility in the future.  ISTM that explicit streaming really should be done with smaller, independent frames.

Section 5.6, "Note that a particular text frame might include a partial UTF-8 sequence, however the whole message MUST contain valid UTF-8"
This requirement is meaningless, since the concept of a "message" is not defined here.  Suggest going back to a requirement that a frame MUST contain valid UTF-8 (i.e., that it breaks at code-point boundaries).  

Section 8
Should be moved to Section 5.6.  It really only applies to text frames, and even then only if text frames are required to be UTF-8.

Section 10
In this section, and overall, it would be helpful if this document could briefly describe the browser/JS model and assign some terms that can be used consistently throughout. 

Section 10.2, "... should only respond with the corresponding "Sec-WebSocket-Accept" if it is an accepted origin. "
If I understand this correctly, the server causes the handshake to fail by omitting the "Accept".  Shouldn't it either return an HTTP error or Fail the Websocket Connection_ ?

Section 10.3, "It is necessary that the masking key is chosen randomly for each frame."
Suggested text: "Clients MUST choose a new masking key for each frame, using an algorithm that cannot be predicted by end applications that provide data.  For example, each masking could be drawn from a cryptographically strong random number generator."

Section 10.3, "It is also necessary that once the transmission of a frame from a client has begun, the payload (application supplied data) of that frame must not be capable of being modified by the application."
This seems to further argue against the idea that giant frames are useful.  They're clearly not useful for streaming (the opposite is suggested in Section 5.4, see above), since the application would have to provide all the data at once.  

Section 10.3
This section should note that even given the masking constraints in this document, proxies are still vulnerable to poisoning by non-browser clients that do not perform masking.

Section 10.4
Suggest making this a "SHOULD" or even "MUST".  If your implementation does not constrain these things, then it will be vulnerable to exhaustion attacks.

Section 10.6
[W3C.REC-wsc-ui-20100812] doesn't actually say anything substantive about how to choose ciphersuites, just that they MUST NOT be on the "export" list.  Suggest removing or replacing with a better reference, maybe RFC 3766?

---

From: Alexey Melnikov <[email-masked]>
Date: Sat, 03 Sep 2011 11:24:06 +0100

>Hey all,
Hi Richard,
Thanks for the re-review and additional comments. My answers below.

>This paragraph has been removed in -13.
>
No, it got moved to its own section "Implementation-Specific Limits" 
under the "Security Considerations"

>While the "MAY" doesn't specify a requirement, it seems like it would be helpful to implementers in light of the exhaustion/DoS possibilities presented by huge frames and fragmentation.  I would even argue that it should be a "SHOULD".
>
I am Ok with changing MAY to SHOULD.

>This caveat seems to invite breakage, especially since there are no extensions defined and no examples given of what sort of semantics might be attached.
>
This is an escape clause, in case we need it in the future. But this is 
not really different from what the document already allows now: 
interpetation of frame payloads in presence of extensions is up to 
extensions (modulo the framing structure).

>(I'm guessing this has to do with 'deflate'?)  At the very least, it seems like there should be a requirement that when an intermediary sees an extension that it doesn't understand, it MUST NOT fragment or coalesce frames.
>
This requirement is already in the spec. In Section 5.4:

   o  An intermediary MUST NOT change the fragmentation of a message if
      any reserved bit values are used and the meaning of these values
      is not known to the intermediary.

   o  An intermediary MUST NOT change the fragmentation of any message
      in the context of a connection where extensions have been
      negotiated and the intermediary is not aware of the semantics of
      the negotiated extensions.

>Same considerations apply here.  This note seems to encourage behavior that will cause incompatibility in the future.  ISTM that explicit streaming really should be done with smaller, independent fr…
As above. I believe the current text reflects a compromise after an 
August long debate on the issue.

>This requirement is meaningless, since the concept of a "message" is not defined here.
>
It was defined earlier in the document.

>Suggest going back to a requirement that a frame MUST contain valid UTF-8 (i.e., that it breaks at code-point boundaries).
>
I am afraid there is WG consensus on the current proposal.

>Should be moved to Section 5.6.  It really only applies to text frames, and even then only if text frames are required to be UTF-8.
I think it also applies to the handshake itself (in presence of possible 
extensions).

>If I understand this correctly, the server causes the handshake to fail by omitting the "Accept".
>
This section doesn't define normative behaviour

>Shouldn't it either return an HTTP error or Fail the Websocket Connection_ ?
>
Yes. Any suggestions how to make this clearer?

>Suggested text: "Clients MUST choose a new masking key for each frame, using an algorithm that cannot be predicted by end applications that provide data.  For example, each masking could be drawn fr…
Ok, I've inserted your text into my copy of the draft.

>This seems to further argue against the idea that giant frames are useful.
>
Yes.

>They're clearly not useful for streaming (the opposite is suggested in Section 5.4, see above), since the application would have to provide all the data at once.  
>
>Section 10.3
Ok.

>[W3C.REC-wsc-ui-20100812] doesn't actually say anything substantive about how to choose ciphersuites, just that they MUST NOT be on the "export" list.  Suggest removing or replacing with a better re…
A change of the reference is probably needed. Not sure if RFC 3766 is 
suitable though, I need to reread it.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sat, 3 Sep 2011 12:22:05 +0200

> This requirement is meaningless, since the concept of a "message" is not defined here.  Suggest going back to a requirement that a frame MUST contain valid UTF-8 (i.e., that it breaks at code-point…

No please. This has been already discussed.

Imagine I must send a very big WS UTF-8 message and due to max frame
size requeriments (still to know how such requiremente is
"negotiated") I need to split it in N frames. This feature would work
at the very transport core layer.

Probably I have a function that splits the whole WS message into
chunks of N bytes (I mean "bytes" because I do know the max frame size
in *bytes*), so such function just counts N bytes from the WS message
and generates a frame. Please don't force such function to be
Unicode/UTF-8 aware, no please.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 10:43:38 -0400

> Unicode/UTF-8 aware, no please.

Clearly it already has to be WebSocket aware, and it already has to read the opcode in order to distinguish data frames from control frames.  Adding on a requirement to break at code point boundaries does not seem hugely onerous.  It's three lines of C:

/* 
uint8_t *new_frame_start = *old_frame_start;
new_frame_start += DESIRED_FRAME_LENGTH;
*/
if (opcode & 0x0f == 0x01) { /* If this is a text frame */
    while (*new_frame_start & 0xc0 == 0x80) { /* While inside a code point */
        new_frame_start--; /* Back up one octet */
    }
    /* new_frame_start is now at the beginning of a code point */
}

In contrast, *not* requiring breaking at UTF-8 code points means that clients can't do any meaningful validation on text frames.  Which means you might as well get rid of text frames entirely.

--Richard

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 6 Sep 2011 16:47:44 +0200

> Clearly it already has to be WebSocket aware, and it already has to read the opcode in order to distinguish data frames from control frames.  Adding on a requirement to break at code point boundari…

Yes it is : you have to process all the bytes. You can't use splicing
to forward XXX bytes between one socket and another, for instance,
which precisely is what a number of intermediaries will do.

Regards,
Willy

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 10:51:10 -0400

No, you have to process at most three bytes, four if you include the opcode.  See sample code.
--Richard

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 07:58:34 -0700

> In contrast, *not* requiring breaking at UTF-8 code points means that clients
> can't do any meaningful validation on text frames.  Which means you might
> as well get rid of text frames entirely.

Why?

You can do streaming validation of UTF-8 without requiring frame boundaries to
observe UTF-8 code point boundaries.

In Python you can do that i.e. using

codecs.getincrementaldecoder('utf-8')()

When a frame does not end on code point boundary, one needs to remember
at most 3 bytes to continue validation on next frame.

It would make sense that a peer SHOULD fail a connection upon invalid UTF-8
as soon as it is possible - that means with at most 1 frame delay upon the
start of the byte sequence that was invalid UTF-8.

Anyway: what's the advantage of such an requirement?

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 11:18:40 -0400

> No, it got moved to its own section "Implementation-Specific Limits" under the "Security Considerations"

Yeah, sorry, wrote that before I got to the Security Considerations :)

> I am Ok with changing MAY to SHOULD.

I'm assuming from your response below that you're OK with going to MUST as well?

>     the negotiated extensions.

Thanks, I had missed those requirements.  

> I think it also applies to the handshake itself (in presence of possible extensions).

Even still, it would probably be more helpful to have individual recommendations in the handshake and framing sections.

> Yes. Any suggestions how to make this clearer?

OLD: 
"
Servers that are not intended to process input from any Web page but only for certain sites SHOULD verify the "Origin" field is an origin they expect, and should only respond with the corresponding "Sec-WebSocket-Accept" if it is an accepted origin.
"
NEW:
"
Servers that are not intended to process input from any Web page but only for certain sites SHOULD verify the "Origin" field is an origin they expect.  If the origin indicated is unacceptable to the server, then it SHOULD respond with an HTTP 403 Unauthorized error response and _Fail the WebSocket Connection_.
"

>> This section should note that even given the masking constraints in this document, proxies are still vulnerable to poisoning by non-browser clients that do not perform masking.

Suggested text:
"
Despite the protection provided by masking, non-compliant HTTP proxies will still be vulnerable to poisoning attacks of this type by clients and servers that do not apply masking.
"

>> Suggest making this a "SHOULD" or even "MUST".  If your implementation does not constrain these things, then it will be vulnerable to exhaustion attacks.

So you're changing this to MUST?

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 11:23:41 -0400

> at most 3 bytes to continue validation on next frame.

If frames are valid utf-8, then you don't need to keep any state (on either end of the connection).

> Anyway: what's the advantage of such an requirement?

The advantage is frame-wise validation instead of message-wise validation.  As you point out, it's not a huge distinction, more "be conservative in what you send".  It just seems unnecessarily sloppy not to have frame boundaries coincide with code point boundaries.

--Richard

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 11:29:19 -0400

> I strongly propose changing the meaning of 1007 status code from:
> 
>      1007 indicates that an endpoint is terminating the connection
>      because it has received data that was supposed to be UTF-8 (such
>      as in a text frame) that was in fact not valid UTF-8 [RFC3629].
> 
> to:
> 
>      1007 indicates that an endpoint is terminating the connection
>      because it has received a message that was supposed to be UTF-8
>      that was in fact not valid UTF-8 [RFC3629].

This makes sense to me, given the clarification around what "messages" are.  One slight revision just for succinctness:
"
   1007 indicates that an endpoint is terminating the connection
   because it has received a text message that was not valid UTF-8 [RFC3629].
"
Text messages are the only ones in this spec that have to be UTF-8, and future things that are also UTF-8 should have their own error codes.

Note that this is independent of whether validation is required on a frame or message level.

--Richard

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 17:22:00 +0200

> Clearly it already has to be WebSocket aware, and it already has to read the opcode in order to distinguish data frames from control frames.  Adding on a requirement to break at code point boundari…

No please. WS framing is like a "transport" layer, not application layer.

to:

WS message format MUST be validated when receiving all the frames
belonging to such message, as message inspection/usage belongs to the
WS application, rather than the WS "transport" layer (frames).

As I've said before, these issues are caused due to the lack of
*logical layers* in the protocol spec.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 17:39:55 +0200

> If frames are valid utf-8, then you don't need to keep any state (on either end of the connection).

But if I need to split a big UTF-8 message into several frames (due
some still unknown max frame size negotiation) I don't want to care
about splitting the UTF-8 message in valid "UTF-8 string". I just want
to care about counting *bytes*, as frame size is determined by payload
*byte* size rather than UTF-8 symbols.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 17:42:06 +0200

> Note that this is independent of whether validation is required on a frame or message level.

Hi Richard, I've started a new thread suggesting this change for 1007
status code. Could you please reply there with your suggestion?

Thanks a lot.

PS: I agree with your proposal in your mail.
PSS: Why do you say that the spec does not clarify "what a message
is"? IMHO it does.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 09:03:19 -0700

> > When a frame does not end on code point boundary, one needs to
> > remember at most 3 bytes to continue validation on next frame.
> 

You do need to keep at least the opcode of the first message frame, since
it determines the type of the whole message and the continuation state,
since you need to identify a protocol violation when you receive a
continuation frame when there is nothing to continue or a frame with FIN=1
but opcode != 0 when a continuation was expected.

Thats 4 bits, but you need state.

You also need state even for unfragmented messages whenever the
frame size exceed the amount which can buffered (and a streaming API
is in place).

> > It would make sense that a peer SHOULD fail a connection upon invalid
> > UTF-8 as soon as it is possible - that means with at most 1 frame
> > delay upon the start of the byte sequence that was invalid UTF-8.
> >
> The advantage is frame-wise validation instead of message-wise validation.
> As you point out, it's not a huge distinction, more "be conservative in what
> you send".  It just seems unnecessarily sloppy not to have frame boundaries
> coincide with code point boundaries.

How do you validate a frame of 2^63 octets?

Message-based/frame-based validation does not help. One needs incremental
/streaming validation.

And if you have incremental validation, there is no need to have frame boundaries
on whole code points. The incremental validator just keeps it's internal state
(of at most 3 bytes) and you feed it the next chop of octets untils it bails "invalid
UTF-8", upon which the connection is immediately failed.

I really don't get the problem ..

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 6 Sep 2011 18:22:56 +0200

> No, you have to process at most three bytes, four if you include the opcode.  See sample code.

I think you misunderstood me. When you receive 40kB of UTF-8 text, if
you want to stop on frame boundaries, you have to parse the data anyway.
Even if you just want to focus on the last bytes, you have to prevent
yourself from blindly forwarding the whole frame in order to check the
last bytes that you probably don't have yet, which significantly reduces
the benefits of splicing and makes the processing quite more complex.

Really, as it was stated many times, a recipient should not consider a
single frame as containing valid contents, just like data can be split
across multiple TCP packets without affecting their meaning.

I think the point you raised in fact is that having an encoding type
on a frame does not make much sense and it only makes sense on a whole
message.

Regards,
Willy

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 09:22:40 -0700

> >> While the "MAY" doesn't specify a requirement, it seems like it would be
> helpful to implementers in light of the exhaustion/DoS possibilities
> presented by huge frames and fragmentation.  I would even argue that it

Why should that impose exhaustion/DoS possibilities?

A WS impl. offering a streaming API has no problem.
A WS impl. offering a frame-based API can fail as soon as the buffered amount for a frame exceeds some limit.
A WS impl. offering a message-based API can fail as soon as the total buffered amount for the message exceeds some limit.

All of these seem pretty straight forward. Where is the attack surface?

> should be a "SHOULD".

I'm not sure: does this refer to 10.4.  Implementation-Specific Limits?

So you suggest an implementation MUST impose limits on frame size AND
message size?

If that is your suggestion (which I hope not, since it's .. breathtaking), I really would
welcome a broad discussion within the WG ..

There was a long and heated debate about announcing frame-size limits and related error codes.
Never (as far as I know) was there discussion about limiting message size.

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 09:39:55 -0700

> * Richard L. Barnes wrote:
> That's somewhat misleading. If you accept for instance both binary and text
> frames, you have to maintain the type of the first frame so you can reject
> continuation frames of the wrong type. You may also have to main- tain state
> coming from extension data or your protocol may require other state to be
> maintained. A minimal byte-oriented UTF-8 validator has nine states
> http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ and that seems less

very cool. thanks!

> onerous to maintain than having fragmenting senders and forwarders to find
> where character and byte boundaries coincide (you need to have the
> encoded text available and re-sychronize to character boundaries, or have
> the character stream available with analyze the encoded widths, or you have
> to include padding within the text, to start sending).

absolutely.

In total:

3 bits: opcode of first frame
1 bit: continuation state
4 bit: UTF-8 DFA state
============

1 octet state

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 09:47:03 -0700

> 1 bit: continuation state

forgot of course:

for servers:

client mask (4 octets)
last frame end % 4 : 2 Bits => to know where within mask to start for unmasking the next masked frame received

Plus any extension state as Björn already mentioned.

Whatever. There is state anyway. WS is not stateless.

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 12:53:01 -0400

> All of these seem pretty straight forward. Where is the attack surface?

In all of these examples, the implementation is imposing "some limit" (the streamer just has an effective zero limit).  The exhaustion/DoS possibilities arise when an implementation doesn't enforce a limit -- just keeps growing the buffer as long as frames keep coming.  That's the reason for making the recommendation for "some limit" a MUST instead of a MAY -- if you don't enforce some limit, then someone on the other end can force you to accept unlimited data.

> Never (as far as I know) was there discussion about limiting message size.

I would say that message size is probably the MUST.  Note, though, that a limit on message size implies a limit on frames; since messages are made of frames, any individual frame can't exceed the message limit.

I would also be OK with carving out an exception for streaming, but there it should be noted that the app on the receiving end of the streaming should implement similar limits.  

--Richard

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 12:55:08 -0400

Well, ok.  No state related to UTF-8.  Any intermediary that deals with fragmentation will have to remember the opcode/extensions.

--Richard

On Sep 6, 2011, at 12:38 PM, Bjoern Hoehrmann wrote:

> That's somewhat misleading. If you accept for instance both binary and
> text frames, you have to maintain the type of the first frame so you can
> reject continuation frames of the wrong type. You may also have to main-
> tain state coming from extension data or your protocol may require other
> state to be maintained. A minimal byte-oriented UTF-8 validator has nine
> states http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ and that seems less
> onerous to maintain than having fragmenting senders and forwarders to
> find where character and byte boundaries coincide (you need to have the
> encoded text available and re-sychronize to character boundaries, or
> have the character stream available with analyze the encoded widths, or
> you have to include padding within the text, to start sending).
> -- 
> Björn Höhrmann · mailto:[email-masked] · http://bjoern.hoehrmann.de
> Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
> 25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 12:58:09 -0400

> last frame end % 4 : 2 Bits => to know where within mask to start for unmasking the next masked frame received

Server shouldn't need to remember this, since each fragmented frame comes with its own masking key.  At least that's how I read the spec; there's nothing in Section 5.4 that seems to indicate that masking keys get carried over from one fragment to another.

> Whatever. There is state anyway. WS is not stateless.

Yep.  I was just talking about state related to UTF-8 processing.

--Richard

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 10:00:25 -0700

> Server shouldn't need to remember this, since each fragmented frame
> comes with its own masking key.  At least that's how I read the spec; there's
> nothing in Section 5.4 that seems to indicate that masking keys get carried
> over from one fragment to another.

yep, you are right, sloppyness on my side. what I wanted to say:

"=> to know where within mask to start for unmasking the next _chunk of octets_ received"

it's only need with a WS implementation capable of full streaming, that
is i.e. processing frames of 2^63 length.

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 6 Sep 2011 10:23:07 -0700

> > A WS impl. offering a message-based API can fail as soon as the total
> buffered amount for the message exceeds some limit.
> >
> In all of these examples, the implementation is imposing "some limit" (the
> streamer just has an effective zero limit).  The exhaustion/DoS possibilities
> arise when an implementation doesn't enforce a limit -- just keeps growing
> the buffer as long as frames keep coming.  That's the reason for making the

Such an implementation is simply broken.

> recommendation for "some limit" a MUST instead of a MAY -- if you don't
> enforce some limit, then someone on the other end can force you to accept
> unlimited data.

Why? One can simply fail the connection. How can a peer force one
exhaust memory if one doesn't want to? And who wanted to deliberately
exhaust memory? The only reason I can think of this might happen is because
the implementation has no safeguards built in.
 
> > If that is your suggestion (which I hope not, since it's ..
> > breathtaking), I really would welcome a broad discussion within the WG ..
> >
> I would say that message size is probably the MUST.  Note, though, that a
> limit on message size implies a limit on frames; since messages are made of
> frames, any individual frame can't exceed the message limit.

This might trigger a long debate.

Just 1 example: an intermediary (an implementation in the sense of 10.4)
imposes a message size limit of 64k for whatever reasons.

Result: endpoints will be need to invent another layer on top of WS to
fragment app messages into WS messages.

Please not. Intermediaries can fragment/coalesce (in the absence of
active extension or when extension is active which allows and is
understood by intermediary), but it MUST process messages of
any size.
 
> 
> I would also be OK with carving out an exception for streaming, but there it
> should be noted that the app on the receiving end of the streaming should
> implement similar limits.
> 
> --Richard

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 19:37:56 +0200

> In all of these examples, the implementation is imposing "some limit" (the streamer just has an effective zero limit).  The exhaustion/DoS possibilities arise when an implementation doesn't enforce…

This is not a good argument. Think in HTTP. I can send an HTTP request
with "infinite" headers to a HTTP server expecting that the server
would buffer all of them and suffer of DoS. See:

  http://ha.ckers.org/slowloris/

And note that HTTP protocol does NOT provide something like "HTTP
headers max size" negotiation at all. It's up to the HTTP server to
determine whether to consider incoming request as a DoS or not and act
according.

And what I've explained aslo applies to any other headers-based text
protocol and others (SIP, XMPP, FTP....).

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 13:41:21 -0400

Giant WebSocket messages are a new vector, however.

The only point here is to point out the new vector and recommend healthy implementation practices.  It's an implementation recommendation, not an interoperability concern.  

Wouldn't you agree that HTTP servers would be less vulnerable to SlowLoris if they imposed limits on the number of HTTP headers of the length of time that a request must take?  All I'm suggesting is that this document suggest similar good habits.

--Richard

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 19:52:48 +0200

> Wouldn't you agree that HTTP servers would be less vulnerable to SlowLoris if they imposed limits on the number of HTTP headers of the length of time that a request must take?  All I'm suggesting i…

I can agree on that, but just if it's within something like a
"Guidelines" section in the draft.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Tue, 06 Sep 2011 18:38:01 +0200

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 06 Sep 2011 21:26:02 +0100

>Server shouldn't need to remember this, since each fragmented frame comes with its own masking key.  At least that's how I read the spec; there's nothing in Section 5.4 that seems to indicate that m…
Correct.

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 06 Sep 2011 22:19:19 +0100

>I'm assuming from your response below that you're OK with going to MUST as well?
I don't think it makes much difference here, SHOULD is strong enough. 
But I can make it a MUST if you insist.

>Servers that are not intended to process input from any Web page but only for certain sites SHOULD verify the "Origin" field is an origin they expect.  If the origin indicated is unacceptable to the…
Thinking more about this: there is no reason to "Fail the WebSocket 
Connection" (as this implies TCP connection closure), just rejecting 
with 403 is sufficient. I will reword your text to say that.

>Despite the protection provided by masking, non-compliant HTTP proxies will still be vulnerable to poisoning attacks of this type by clients and servers that do not apply masking.
Ok.
Note that that is not quite correct is masking is not optional for 
clients, but this is still under discussion.

>So you're changing this to MUST?
Ok :-).

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 17:52:27 -0400

> I don't think it makes much difference here, SHOULD is strong enough. But I can make it a MUST if you insist.

I was just thinking "MUST" because I couldn't think of an exception case.  It's up to you.

>>>> They're clearly not useful for streaming (the opposite is suggested in Section 5.4, see above), since the application would have to provide all the data at once.  Section 10.3
> Note that that is not quite correct is masking is not optional for clients, but this is still under discussion.

Regardless of what this protocol does, the vulnerability will still be there, and you can still exploit it, e.g., with the code that was used in the experiment.  It's also not completely unimaginable that someone would make an implementation with configurable masking, if only to re-use framing code between client and server.

>> So you're changing this to MUST?

Ok!

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 06 Sep 2011 23:47:06 +0100

Richard L. Barnes wrote:

>In contrast, *not* requiring breaking at UTF-8 code points means that clients can't do any meaningful validation on text frames.
>
That is not entirely true. One can check if a full Unicode character was 
received at the end of a frame and just buffer enough from the previous 
frame to continue validation.

There are also other types of possible UTF-8 brokeness, as overlong 
sequences, invalid bytes, etc. These can also be detected early.

>Which means you might as well get rid of text frames entirely.
>

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 7 Sep 2011 11:25:17 +1000

> Clearly it already has to be WebSocket aware, and it already has to read the opcode in order to distinguish data frames from control frames.  Adding on a requirement to break at code point boundari…

It is more difficult than that.

For example, I currently fragment frames when a buffer fills up.
During the filling I'm not looking at the bytes and don't care if it
is a text or binary frame.      If I have to fragment on a utf-8 char
boundary, then I'll have to a) handle text and binary differently b)
actually inspect the bytes rather than just bulk copy them c) deal
with residue bytes left over that could not be put into the fragement

This would be a throw it all out and start again kind of change for me.