Security/Reviews/Firefox6/ReviewNotes/WebSockets
Preliminary look at Protocol and DOM specs
6/1/2011 - bsmith, dchan, dveditz, bsterne, imelven
netwerk/protocol/websocket/nsIWebSocketProtocol.idl netwerk/protocol/websocket/nsWebSocketHandler.cpp content/base/nsIWebSocket.idl
non-protocol uses of ws:// wss:// URLs (addressbar, <img> etc)
Mixed Content:
- Must change code so that https:// web page disallows ws:// sockets (wss:// only) or trigger mixed modes
Redirects:
- Redirects are currently pref'd off, may be allowed in future; this pref'd off code was identified as problematic. Change code to ignore pref and never redirect?
- If redirects are allowed then an originally secure socket can redirect to an insecure site
- http://dev.w3.org/html5/websockets/#dom-websocket says redirects are NOT allowed, anything other than an initial 101 response is a fatal error
- The IETF protocol says non-101 responses should be handled as a normal http response
Do sockets check with nsIContentPolicy listeners? they should!
- Patrick probably needs help writing the tests for this.
- nsIContentPolicy is used for CSP *and* other content restriction mechanisms
Is HSTS implemented correctly? Does HSTS apply to the whole server or to a specific port? Look at the spec? We do agree that HSTS applies to WebSockets.
Need to audit the code for protocol-specific checks (especially for HTTP(S)) to make sure they were updated for WebSockets. (browser.js for address bar.)
What URI flags are used for WS:// and WSS://? checkLoadURI?
Should we attempt to load an external handler for ws:// or wss:// handler?
Load an iframe that has a websocket connection in it. Does this allow any attacks? Frames. What if the framed document has document.domain set?
evil.mit.edu
document.domain = mit.edu
cs.mit.edu
document.domain = mit.edu
Is this case, can the documents share a websocket? What is the Sec-WebSocket-Origin the original document, or the document.domain? What happens if you change document.domain when a WebSocket is active, does the WebSocket remain valid? (Blake, Jonas, JST.) Should it be similar to XSXHR? Is XSXHR implementation even right? Browser makers are trying to avoid adding document.domain handling to new specs, according to dveditz. (LocalStorage might not work, for example, according to dveditz.)
Compression mechanism - disabled by pref
Servers might not expect us to reuse a web connection as a websocket connection. Need to investigate whether we need to change our connection handling. W3C specification is unclear; IETF specification is unclear; specs do not match in specified behavior.
Cookies, HTTP authentication, Client certs, need cross-site cookie protection, HTTP-only cookies need to be properly handled. Compare to XHR with CORS. Need to write spec for how cookies are supposed to be handled and then check implementation against that spec. What happens when a 401 response is returned? How does HTTP auth work with websockets? How do client certs work in WebSockets (and XHR)?
W3C spec has specific requirements regarding cookies.
HTTP-only cookies, Secure Cookies
CORS-light - need to better understand differences between CORS and WebSockets CORS lite
WebSockets in workers - different principle
Malicious Servers:
* Bad framing for buffer overflows and parsing errors * Control frames mixed in with data frames, potential confusion regarding mixing data from frames * Code audit + fuzzing server
Client attacking servers (e.g. server not expecting websockets at all).
Only one connecting connection to a particular host/port pair to prevent DoS according to the TLS spec (in security considerations). Do we implement this? Are there security problems with implementing this restriction? (See also proxy considerations.)
Should websockets be limited by the global limit of the number of connections per host?
Spec requires TLS Server Name Inidication for WSS. Implementation doesn't require this; PSM implements fallback to non-TLS SSL2.0/3.0 handshake without SNI. How does this work with TLS proxy to non-TLS websocket?
What happens on private browsing transitions? Do we send a close frame? Do we wait for a close? Do we clean up correctly/properly?
Are WebSockets responses cached? It shouldn't be.
Chrome consideratoins:
* HTTP auth spoofing * Client certificate spoofing * Mixed content indicators * WS:// WSS:// in the address bar * Are we registering a handler for it? * On the command line
Can Chrome use websockets? If so, what principle gets sent? What happens when add-ons use it? What cookies/HTTP auth/etc.? Can JetPack get WebSockets access? Do we need to enable JetPack access?
Can Workers use websockets? If so, what principle gets sent?
URI parsing needs to be checked to make sure we are parsing WS:// and WSS:// URIs correctly, and not mis-interpreting HTTP URI constructions. Should be be silently stripping fragments? Are we?
What happens when we unregister callbacks? Need to make sure we don't crash on receiving data or any other notification that would cause a callback to be called.
Reusing connectoins deemed problematic. Need to understand how we would handle data after client closed connection and/or server indicated that it closed the connection and isn't intending to send more data, so that we don't interpret any following data as a response to a future request.
Need to handle server flooding us with data. Need to implement a maximum receive buffer size. Also, buffer size is increased linearly, instead of geometrically.
Is allocation used fallable?
Similarly, clients trying to send too much data that isn't being recv'd by the server, we don't want to DoS ourselves. Does the W3C spec have a way of saying "you are sending too much data; back off?" Is this implemented? Can this lead to OOM unnecessarily? It seems the spec is bad, because it doesn't expose the max buffered amount.
http://dev.w3.org/html5/websockets/#dom-websocket-send http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07#section-5
Spec wierdness: "If the connection is closed, this attribute's [bufferedAmount] value will only increase with each call to the send() method (the number does not reset to zero once the connection closes)." What happens when you send data in closed state?
Example from test-bug-603750-websocket.js: window.addEventListener("load", function () {
var ws1 = new WebSocket("ws://0.0.0.0:81");
ws1.onopen = function() {
ws1.send("test 1");
ws1.close();
};
var ws2 = new window.frames[0].WebSocket("ws://0.0.0.0:82");
ws2.onopen = function() {
ws2.send("test 2");
ws2.close();
};
}, false);