Bug 41327 - WebSocket: Malformed handshake headers in a worker due to rand_s failing
Summary: WebSocket: Malformed handshake headers in a worker due to rand_s failing
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows XP
: P2 Normal
Assignee: Yuta Kitamura
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-28 21:17 PDT by Yuta Kitamura
Modified: 2010-06-30 08:47 PDT (History)
5 users (show)

See Also:


Attachments
Patch (3.40 KB, patch)
2010-06-28 21:36 PDT, Yuta Kitamura
no flags Details | Formatted Diff | Diff
Patch (1.58 KB, patch)
2010-06-29 22:43 PDT, Yuta Kitamura
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yuta Kitamura 2010-06-28 21:17:35 PDT
Derived from Chromium bug: http://crbug.com/47390

WebSocket in a worker may send malformed handshake headers such as:

  Sec-WebSocket-Key1:  !0
  Sec-WebSocket-Key2:  !0

where each key contains a space in its front (WebSocket specification explicitly forbids a leading or trailing space in WebSocket keys).

There are two reasons why such a broken handshake is sent:
  - WebSocketHandshake has a bug to put a space in front of a key, and
  - Windows' rand_s() may fail due to Chromium's sandbox, and randomNumber (wtf/RandomNumber.h) does not check the failure and always returns zero.
Comment 1 Yuta Kitamura 2010-06-28 21:36:22 PDT
Created attachment 59982 [details]
Patch
Comment 2 Fumitoshi Ukai 2010-06-28 21:40:46 PDT
Comment on attachment 59982 [details]
Patch

LGTM for WebSocketHandhshake.cpp change.
I'm not sure it's ok to fallback to rand().  I believe sandbox should be fixed.
Comment 3 Yuta Kitamura 2010-06-28 21:56:45 PDT
(In reply to comment #2)
> (From update of attachment 59982 [details])
> LGTM for WebSocketHandhshake.cpp change.
> I'm not sure it's ok to fallback to rand().  I believe sandbox should be fixed.

Yes, Chromium's sandbox is the root cause. However, I think WebKit also needs to be prepared for rand_s() failure because it is explicitly stated that it may fail (http://msdn.microsoft.com/en-us/library/sxtz2fa8(v=VS.80).aspx).

I may change my mind if other folks disagree on the randomNumber change, though.
Comment 4 Alexey Proskuryakov 2010-06-29 09:50:41 PDT
I don't think it's OK for randomNumber() to sometimes return cryptographically strong numbers, and sometimes silently fall back to rand(). AFAIK, the main reason for having strong randomness in WebCore is preserving user privacy, as servers can track visitors by random parts of their requests.

I'm not sure how to best address this. Maybe use arc4random, as on Darwin?
Comment 5 Adam Roben (:aroben) 2010-06-29 09:58:33 PDT
(In reply to comment #4)
> I don't think it's OK for randomNumber() to sometimes return cryptographically strong numbers, and sometimes silently fall back to rand(). AFAIK, the main reason for having strong randomness in WebCore is preserving user privacy, as servers can track visitors by random parts of their requests.
> 
> I'm not sure how to best address this. Maybe use arc4random, as on Darwin?

Is arc4random available on Windows?

I agree that silently falling back to a non-secure implementation is not a good way to go.
Comment 6 Alexey Proskuryakov 2010-06-29 10:17:39 PDT
On a second thought, arc4random reads /dev/urandom, so it's probably affected by the same sandbox issues.
Comment 7 Yuta Kitamura 2010-06-29 22:37:10 PDT
OK, I'm sold. I will create a patch that only fixes a WebSocket bug that inserts a space in an invalid position.
Comment 8 Yuta Kitamura 2010-06-29 22:39:50 PDT
Note that we have found a way to workaround the sandbox: we need to call rand_s() at least once before entering the sandbox, otherwise it fails loading a DLL dynamically.
Comment 9 Yuta Kitamura 2010-06-29 22:43:10 PDT
Created attachment 60085 [details]
Patch
Comment 10 Fumitoshi Ukai 2010-06-29 22:50:19 PDT
Comment on attachment 60085 [details]
Patch

LGTM
Comment 11 Alexey Proskuryakov 2010-06-29 23:47:10 PDT
Comment on attachment 60085 [details]
Patch

r=me, but a stripWhiteSpace() call on the result would have looked less alarming (even if we're losing a tiny bit of randomness that way).

>    DEFINE_STATIC_LOCAL(String, randomChars, (randomCharacterInSecWebSocketKey));
>     DEFINE_STATIC_LOCAL(String, spaceChar, (" "));

I'd have added String::insert(UChar) for this. But it's not new with this patch.
Comment 12 Yuta Kitamura 2010-06-29 23:58:34 PDT
(In reply to comment #11)
> (From update of attachment 60085 [details])
> r=me, but a stripWhiteSpace() call on the result would have looked less alarming (even if we're losing a tiny bit of randomness that way).

The number of spaces is significant for calculating the challenge response. We should not remove them silently.
Comment 13 WebKit Commit Bot 2010-06-30 01:00:42 PDT
Comment on attachment 60085 [details]
Patch

Clearing flags on attachment: 60085

Committed r62163: <http://trac.webkit.org/changeset/62163>
Comment 14 WebKit Commit Bot 2010-06-30 01:00:48 PDT
All reviewed patches have been landed.  Closing bug.
Comment 15 Alexey Proskuryakov 2010-06-30 08:47:43 PDT
> The number of spaces is significant for calculating the challenge response. 

Yes, you are right - I didn't realize that "number" was also an output of the algorithm.