Re: Hello from Mozilla

2009-08-13 Thread Ian Hickson
On Wed, 5 Aug 2009, Amos Jeffries wrote:
 On Wed, 5 Aug 2009 00:57:18 + (UTC), Ian Hickson i...@hixie.ch wrote:
  On Thu, 30 Jul 2009, Robert Collins wrote:
  On Wed, 2009-07-29 at 23:48 +, Ian Hickson wrote:
   
   Surely once the HTTP server has decided that it can Upgrade, it 
   doesn't actually need to worry about sending back something 
   HTTP-valid at all, since we can just say the entire connection was 
   always using the WebSocket protocol, and was never HTTP.
  
  10.1.2 101 Switching Protocols
  
 The server understands and is willing to comply with the client's
 request, via the Upgrade message header field (section 14.42), for a
 change in the application protocol being used on this connection. The
 server will switch protocols to those defined by the response's
 Upgrade header field immediately after the empty line which
 terminates the 101 response.
  
  So the server has to send a response before switching.
  
  The above text has no normative conformance criteria (the server 
  will is an informative statement that is unsupported as far as I can 
  tell).
 
 Point to note: if webserver fails to switch the WebSockets handshake to
 verify said switch actually occurred will fail. Detecting such bad servers
 and acting properly.
 If web server successfully switched then WebSockets client needs to handle
 the HTTP response correctly and begin to do a WebSockets native handshake
 and verify the link is safe _after_ the 101 message is received.

I don't understand what you are trying to say here.


  In any case, the WebSocket protocol handshake does do a complete HTTP 
  Upgrade including the empty line, it just requires that the handshake 
  be done in a particular way. It's profiling the HTTP spec.
 
 No, our whole point repeated over and over in different ways is that the 
 specd description for the upgrade request is _incomplete_. And does not 
 account for an enormous number of byte-level variations. All of which 
 can be safely discarded without affecting security.

 Being sensitive to whether the server replies 101 Blah versus 101 
 blah absolutely cripples WebSockets. We want to help you fix this 
 problem.

I still do not understand why anything gets crippled. Maybe you could show 
an example of how you expect this problem to occur?


  This is because if it doesn't, how can it say 'I won't upgrade'.
  
  It can just not upgrade. Returning anything but the correct handshake 
  will be treated as a failed connection by the WebSocket client.
 
 Correct.

So why would it need to say I won't upgrade?


  On Thu, 30 Jul 2009, Robert Collins wrote:
   
   Suppose we had no handshake at all, and that there was no data 
   framing, so that as soon as we connected to a port, we could send 
   arbitrary data down.
   
   A Web page, say evil.example.net, could open a Web Socket 
   connection to http://www.corp.example.com/, send it a GET request 
   for /secret-plans, and then forward the contents of the file to a 
   remote host. If they could then trick someone on example.com's 
   intranet to look at this file, and assuming www.corp.example.com 
   did nothing more than rely on connectivitity for authentication 
   (pretty common in small intranets), then evil.example.net could 
   steal the company's secret plans.
  
  Can't the web page just send an ajax request to corp.example.com 
  anyway?
  
  It can't read the response, no.
 
 Can you explain this please?
 AFAIK, Sending a request then closing the connection immediately is the
 only way said response might be unreadable. I don't understand what you
 mean.

A script on a Web page can cause a GET request to be sent to an arbitrary 
URL, but it has no way to obtain the contents of the result of that 
request unless that server opts in (using CORS) to allowing the script to 
see the contents of the response.


  Dumping the ability to look like HTTP altogether is your best bet 
  IMO: even on port 443. For port 443, someone running a websocket 
  server should just not run an HTTPS server there. Or define port 815 
  as websocket/s.
  
  Port 815 is the preferred port, but in certain situations, only ports 
  80 and 443 are allowed, and port 80 is mitm'ed, so that only leaves 
  443.
  
  You don't always have the option of using a different host, that's why 
  we need to share the port sometimes. (There have also been statements 
  to the effect that just sending a new protocol over ports 80 or 443 
  without using the Upgrade mechanism would be a violation of the 
  semantics of those ports.)
 
 Understood. However strange protocols (torrent is one example) on port 80
 can be detected and dealt with easily.
 Something that appears to be perfect HTTP cannot be detected as non-HTTP.
 When HTTP operations are done to the traffic it will break badly and in
 nasty invisible ways.

Could you explain how a WebSocket connection can break in an invisible 
way? An example would be very helpful here.


  If its 

Re: Hello from Mozilla

2009-08-13 Thread Amos Jeffries

Ian Hickson wrote:

On Wed, 5 Aug 2009, Amos Jeffries wrote:

On Wed, 5 Aug 2009 00:57:18 + (UTC), Ian Hickson i...@hixie.ch wrote:

On Thu, 30 Jul 2009, Robert Collins wrote:

On Wed, 2009-07-29 at 23:48 +, Ian Hickson wrote:
Surely once the HTTP server has decided that it can Upgrade, it 
doesn't actually need to worry about sending back something 
HTTP-valid at all, since we can just say the entire connection was 
always using the WebSocket protocol, and was never HTTP.

10.1.2 101 Switching Protocols

   The server understands and is willing to comply with the client's
   request, via the Upgrade message header field (section 14.42), for a
   change in the application protocol being used on this connection. The
   server will switch protocols to those defined by the response's
   Upgrade header field immediately after the empty line which
   terminates the 101 response.

So the server has to send a response before switching.
The above text has no normative conformance criteria (the server 
will is an informative statement that is unsupported as far as I can 
tell).

Point to note: if webserver fails to switch the WebSockets handshake to
verify said switch actually occurred will fail. Detecting such bad servers
and acting properly.
If web server successfully switched then WebSockets client needs to handle
the HTTP response correctly and begin to do a WebSockets native handshake
and verify the link is safe _after_ the 101 message is received.


I don't understand what you are trying to say here.


In any case, the WebSocket protocol handshake does do a complete HTTP 
Upgrade including the empty line, it just requires that the handshake 
be done in a particular way. It's profiling the HTTP spec.
No, our whole point repeated over and over in different ways is that the 
specd description for the upgrade request is _incomplete_. And does not 
account for an enormous number of byte-level variations. All of which 
can be safely discarded without affecting security.


Being sensitive to whether the server replies 101 Blah versus 101 
blah absolutely cripples WebSockets. We want to help you fix this 
problem.


I still do not understand why anything gets crippled. Maybe you could show 
an example of how you expect this problem to occur?




Your protocol definition used byte-level. At the byte-level 'b' (0x97 
IIRC) does not equal 'B' (0x65 IIRC). Thus the response is a different 
byte pattern and a failed WebSocket connection.


One very real example of this would be the web server or an fully 
WebSocket capable intermediary sending back bytes


Your spec section 3.1 sub 12 says:

 12.  Read the first 85 bytes from the server.  If the connection
closes before 85 bytes are received, or if the first 85 bytes
aren't exactly equal to the following bytes, then fail the Web

  [ note the words _exactly equal_ ]

Socket connection and abort these steps.

   48 54 54 50 2f 31 2e 31  20 31 30 31 20 57 65 62
   20 53 6f 63 6b 65 74 20  50 72 6f 74 6f 63 6f 6c
   20 48 61 6e 64 73 68 61  6b 65 0d 0a 55 70 67 72
   61 64 65 3a 20 57 65 62  53 6f 63 6b 65 74 0d 0a
   43 6f 6e 6e 65 63 74 69  6f 6e 3a 20 55 70 67 72
   61 64 65 0d 0a


example #1  suppose there was an intermediary translating 
websockets-over-http to websockets-port-81 which used HTTP to format 
said headers of confirmation.
In all other ways it is fully WebSockets compliant. But sends byte 18 as 
73 (s) instead of 53 (S).
Boom! The entire application is not WebSockets compliant and will fail 
every single transaction that goes through it.



example #2 is where the traffic is processed by an HTTP-only 
intermediary which sees the 'Upgrade:' header and flags the connection 
for transparent pass-thru (This by the way is the desirable method of 
making Squid support WebSockets).


Being a good HTTP relay it accepts these bytes:
  HTTP/1.1 101 Web Socket Protocol Handshake
  Upgrade: WebSocket
  Connection: Upgrade

It violates HTTP by omitting the Via and other headers your spec omits 
to handle.  And passes these on:

  HTTP/1.1 101 Web Socket Protocol Handshake
  Connection: Upgrade
  Upgrade: WebSocket

then moves to tunnel mode for you.

Bang. Another whole network isolated from WebSockets.




This is because if it doesn't, how can it say 'I won't upgrade'.
It can just not upgrade. Returning anything but the correct handshake 
will be treated as a failed connection by the WebSocket client.

Correct.


So why would it need to say I won't upgrade?


To inform MITM that the upgrade is not going to happen and the links 
they have open maybe used for other HTTP things without wasting network 
resources tearing them down and rebuilding.





On Thu, 30 Jul 2009, Robert Collins wrote:
Suppose we had no handshake at all, and that there was no data 
framing, so that as soon as we connected to a port, we could send 
arbitrary data down.


A Web page, say evil.example.net, could open a 

Re: Hello from Mozilla

2009-08-04 Thread Ian Hickson
On Thu, 30 Jul 2009, Robert Collins wrote:
 On Wed, 2009-07-29 at 23:48 +, Ian Hickson wrote:
  
  Surely once the HTTP server has decided that it can Upgrade, it 
  doesn't actually need to worry about sending back something HTTP-valid 
  at all, since we can just say the entire connection was always using 
  the WebSocket protocol, and was never HTTP.
 
 10.1.2 101 Switching Protocols
 
The server understands and is willing to comply with the client's
request, via the Upgrade message header field (section 14.42), for a
change in the application protocol being used on this connection. The
server will switch protocols to those defined by the response's
Upgrade header field immediately after the empty line which
terminates the 101 response.
 
 So the server has to send a response before switching.

The above text has no normative conformance criteria (the server will is 
an informative statement that is unsupported as far as I can tell).

In any case, the WebSocket protocol handshake does do a complete HTTP 
Upgrade including the empty line, it just requires that the handshake be 
done in a particular way. It's profiling the HTTP spec.


 This is because if it doesn't, how can it say 'I won't upgrade'.

It can just not upgrade. Returning anything but the correct handshake will 
be treated as a failed connection by the WebSocket client.


On Thu, 30 Jul 2009, Robert Collins wrote:
  
  Suppose we had no handshake at all, and that there was no data 
  framing, so that as soon as we connected to a port, we could send 
  arbitrary data down.
  
  A Web page, say evil.example.net, could open a Web Socket connection 
  to http://www.corp.example.com/, send it a GET request for 
  /secret-plans, and then forward the contents of the file to a remote 
  host. If they could then trick someone on example.com's intranet to 
  look at this file, and assuming www.corp.example.com did nothing more 
  than rely on connectivitity for authentication (pretty common in small 
  intranets), then evil.example.net could steal the company's secret 
  plans.
 
 Can't the web page just send an ajax request to corp.example.com anyway? 

It can't read the response, no.


 And if it can't, why doesn't the same browser security model prevent 
 websockets being used in the same way?

The same-origin model would prevent any WebSocket traffic at all, since 
it's a different scheme than the document.


  Now, Web Socket has a multi-layered approach to dealing with this.
  
  - there is the handshake, which requires that the server respond with a 
  very specific set of bytes, thus guaranteeing that the server is in fact 
  WebSocket-aware. Any wildcard part to this handshake increases the risk 
  that there will be a server somewhere that can be tricked. For example, if 
  the handshake were HTTP followed by anything followed by WebSocket, 
  then some HTTP servers could be tricked into doing the handshake -- for 
  example, the response to GET /WebSocket on the ietf.org host (not 
  www.ietf.org) includes the word WebSocket in the response.
  
  HTTP servers aren't the only concern, of course; we want the handshake to 
  be as secure as possible against any other protocol that may exist on any 
  server that may be deployed. We don't know what's out there (especially in 
  intranets), so the handshake has to be pretty stringent to make it as 
  unlikely as possible.
 
 Dumping the ability to look like HTTP altogether is your best bet IMO:
 even on port 443. For port 443, someone running a websocket server
 should just not run an HTTPS server there. Or define port 815 as
 websocket/s.

Port 815 is the preferred port, but in certain situations, only ports 80 
and 443 are allowed, and port 80 is mitm'ed, so that only leaves 443.

You don't always have the option of using a different host, that's why we 
need to share the port sometimes. (There have also been statements to the 
effect that just sending a new protocol over ports 80 or 443 without using 
the Upgrade mechanism would be a violation of the semantics of those 
ports.)


  - there is origin checking and location checking, and the location 
  checking isn't just an echo of the original request's data. This makes 
  causing the server to send back particular data harder. (It's also part of 
  our cross-origin security model and our shared hosting support; but that's 
  a separate discussion.)
  
  - there is the framing, which does provide a modicum of protection by 
  forcing another byte in front of the first author-controlled packet sent. 
  (This isn't really a security feature, it's just a lucky accident of the 
  framing that we needed to turn TCP streams into packets.)
 
 To summarise, if I have it right, you want to make sure that *the
 browser* can be sure that corp.example.com really was intending to be a
 websocket server when it opened the connection.

Right.


 If its not, it should bail. That seems reasonable :). We can definitely 
 (and have 

Re: Hello from Mozilla

2009-08-04 Thread Amos Jeffries
On Wed, 5 Aug 2009 00:57:18 + (UTC), Ian Hickson i...@hixie.ch wrote:
 On Thu, 30 Jul 2009, Robert Collins wrote:
 On Wed, 2009-07-29 at 23:48 +, Ian Hickson wrote:
  
  Surely once the HTTP server has decided that it can Upgrade, it 
  doesn't actually need to worry about sending back something HTTP-valid

  at all, since we can just say the entire connection was always using 
  the WebSocket protocol, and was never HTTP.
 
 10.1.2 101 Switching Protocols
 
The server understands and is willing to comply with the client's
request, via the Upgrade message header field (section 14.42), for a
change in the application protocol being used on this connection. The
server will switch protocols to those defined by the response's
Upgrade header field immediately after the empty line which
terminates the 101 response.
 
 So the server has to send a response before switching.
 
 The above text has no normative conformance criteria (the server will
is 
 an informative statement that is unsupported as far as I can tell).

Point to note: if webserver fails to switch the WebSockets handshake to
verify said switch actually occurred will fail. Detecting such bad servers
and acting properly.
If web server successfully switched then WebSockets client needs to handle
the HTTP response correctly and begin to do a WebSockets native handshake
and verify the link is safe _after_ the 101 message is received.

 
 In any case, the WebSocket protocol handshake does do a complete HTTP 
 Upgrade including the empty line, it just requires that the handshake be 
 done in a particular way. It's profiling the HTTP spec.

No, our whole point repeated over and over in different ways is that the
specd description for the upgrade request is _incomplete_. And does not
account for an enormous number of byte-level variations. All of which can
be safely discarded without affecting security.
Being sensitive to whether the server replies 101 Blah versus 101 blah
absolutely cripples WebSockets. We want to help you fix this problem.

 
 
 This is because if it doesn't, how can it say 'I won't upgrade'.
 
 It can just not upgrade. Returning anything but the correct handshake
will 
 be treated as a failed connection by the WebSocket client.

Correct.

 
 
 On Thu, 30 Jul 2009, Robert Collins wrote:
  
  Suppose we had no handshake at all, and that there was no data 
  framing, so that as soon as we connected to a port, we could send 
  arbitrary data down.
  
  A Web page, say evil.example.net, could open a Web Socket connection 
  to http://www.corp.example.com/, send it a GET request for 
  /secret-plans, and then forward the contents of the file to a remote 
  host. If they could then trick someone on example.com's intranet to 
  look at this file, and assuming www.corp.example.com did nothing more 
  than rely on connectivitity for authentication (pretty common in small

  intranets), then evil.example.net could steal the company's secret 
  plans.
 
 Can't the web page just send an ajax request to corp.example.com anyway?

 
 It can't read the response, no.
 

Can you explain this please?
AFAIK, Sending a request then closing the connection immediately is the
only way said response might be unreadable. I don't understand what you
mean.

 
 And if it can't, why doesn't the same browser security model prevent 
 websockets being used in the same way?
 
 The same-origin model would prevent any WebSocket traffic at all, since 
 it's a different scheme than the document.
 
 
  Now, Web Socket has a multi-layered approach to dealing with this.
  
  - there is the handshake, which requires that the server respond with
a
 
  very specific set of bytes, thus guaranteeing that the server is in
  fact
  WebSocket-aware. Any wildcard part to this handshake increases the
  risk
  that there will be a server somewhere that can be tricked. For
example,
  if
  the handshake were HTTP followed by anything followed by
WebSocket,
 
  then some HTTP servers could be tricked into doing the handshake --
for
 
  example, the response to GET /WebSocket on the ietf.org host (not 
  www.ietf.org) includes the word WebSocket in the response.
  
  HTTP servers aren't the only concern, of course; we want the handshake
  to
  be as secure as possible against any other protocol that may exist on
  any
  server that may be deployed. We don't know what's out there
(especially
  in
  intranets), so the handshake has to be pretty stringent to make it as 
  unlikely as possible.
 
 Dumping the ability to look like HTTP altogether is your best bet IMO:
 even on port 443. For port 443, someone running a websocket server
 should just not run an HTTPS server there. Or define port 815 as
 websocket/s.
 
 Port 815 is the preferred port, but in certain situations, only ports 80 
 and 443 are allowed, and port 80 is mitm'ed, so that only leaves 443.
 
 You don't always have the option of using a different host, that's why we

 need to share the port 

Re: Hello from Mozilla

2009-07-30 Thread Henrik Nordstrom
tor 2009-07-30 klockan 10:26 +1000 skrev Robert Collins:

 In corporate networking, TLS MITM is a 'feature': company signed
 certificates are used to sign the TLS connection to the corporate
 firewall, and the firewall validate the SSL connection to the outside
 world. I haven't personally used this, so can't really say much more
 about it. Squid's ssl-bump feature can be used for this, but I believe
 browser config is needed (again on a corporate basis) to tell it that
 this is expected.


Squid ssl-bump isn't yet very polished, but also far from alone in doing
this. It is a fairly common thing in large corporations.

The configuration needed for this SSL interception thing to run smoothly
(in the eyes of users browsing https) is apart from the middleman doing
it that the corporation adds a private CA to the browsers list of
accepted CAs. Once that is done the corporation can freely spoof
certificates for any server, completely breaking SSL end-to-end in ways
the X.509 trust model is supposed to prevent.. but also throwing
certificate based client authentication out the window as this requires
end-to-end.

In essence the level of trust you can place in SSL without manually
inspecting each received certificate is the least amount of trust you
have in any of the CAs installed in your browsers list of universally
trusted CAs and all their CA delegations, official and unofficial..

Regards
Henrik



Re: Hello from Mozilla

2009-07-29 Thread Ian Hickson
On Sat, 18 Jul 2009, Amos Jeffries wrote:
  
  But per HTTP specifications such body data is part of the HTTP Upgrade 
  request and should be ignored if switching protocols as part of 
  ignoring the HTTP request which contained the Upgrade request. 
  Consider for example if the request is a POST request, containing a 
  alternative simplex representation of the communication meant to be 
  used by a non-WebSockets server.
 
 Ian:  is that a relevant case? you can spec it in or out as needed.
 
 But I'm thinking out, since the idea here is to setup a TCP-link tunnel 
 then perform authentication handshake inside it. The upgrade request is 
 only to get the MITM/Surrogates to pass it correctly or fail it cleanly.

I'm not sure what you're asking here, sorry.


   3.1.5.4
   A server receiving a valid HTTP Upgrade request to WebSockets
   and which does not accept that WebSockets upgrade MUST send back
   a 4xx or 5xx HTTP response as per section 3.1.5.2.
  
  There is no such requirement in HTTP. Handling Upgrade is purely
  optional and the server is free to ignore Upgrade. Upgrade is a please
  upgrade to one of these protocols if supported.
 
 Meaning HTTP does not care what gets returned...
 
 At the non-101 reply point its not usable as a WebSockets link. This bit 
 is going slightly beyond HTTP in a compatible way and refers to the 
 WebSockets-enabled server rejecting the socket connection.
 
 Ian mentioned many times WebSockets being 'opt-in'. This clause permits 
 'opt-in' to be denied by the server. It's irrelevant to non-WebSocket 
 intermediaries and applies only to WebSocket origin servers. Perhapse 
 that needs to be worded clearer.

I'm not sure exactly what part isn't clear. If you mean some text in the 
Web Socket protocol draft, could you elaborate on what change you are 
requesting?


   The server SHOULD send only the following lines:
   
   HTTP/1.1 101 Web Socket Protocol Handshake
   Upgrade: WebSocket
   Connection: Upgrade
  
  While it's true HTTP does not mandate any headers for 1xx responses, 
  including things like Server is a good idea in 101 responses, and 
  there may also be other headers required by the HTTP operation such as 
  Authentication-Info and possibly other headers as well in future 
  specifications.
 
 Ah yes. Okay.
 Ian: anything else you find useful as required here as well. This is where you
 get the is the mystery server capable of WebSockets info. Being the _right_
 one needs must separate and handled by the WebSockets handshake.
 
 Just only specify it at the string level.  Specifying the order sent is fine
 but confusing because it implies order received. Specifying the order received
 beyond 101 is broken.

I really don't understand what you are asking here. Do you mean that the 
handshake should allow the Upgrade and Connection lines to be sent in 
any order?

Surely once the HTTP server has decided that it can Upgrade, it doesn't 
actually need to worry about sending back something HTTP-valid at all, 
since we can just say the entire connection was always using the WebSocket 
protocol, and was never HTTP.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-29 Thread Robert Collins
On Wed, 2009-07-15 at 00:51 +, Ian Hickson wrote:
 
 If there are any bytes allowed from the client or the server before
 the 
 handshake starts, then it is no longer secure. The idea is to make
 sure 
 you can't smuggle though payloads from other protocols, since
 otherwise 
 you could use WebSocket to connect to services that aren't expecting
 it. 

Then don't use port 80!

If you use port 80 you must expect the following:
 - many users will be unable to connect directly to your service
 - many users will think they are connecting directly to your service
but will not actually be doing so

AIUI websockets is:
 * TCP +
 * authentication

I don't really see this having *anything* to do with HTTP.

Perhaps I'm missing something fundamental, but as it stands, I think it
would be more robust, and more secure to say:
Websockets is on IANA port 
the authentication handshake for a websocket server is 
after that its a bidirectional stream of octects just like TCP
If a browser needs to get through a firewall to connect to the websocket
server, we recommend the use of a SOCKS proxy an HTTP proxy supporting
the CONNECT method.

What drives the desire to live on port 80?

-Rob


signature.asc
Description: This is a digitally signed message part


Re: Hello from Mozilla

2009-07-29 Thread Robert Collins
On Wed, 2009-07-29 at 23:48 +, Ian Hickson wrote:
 
 Surely once the HTTP server has decided that it can Upgrade, it
 doesn't 
 actually need to worry about sending back something HTTP-valid at
 all, 
 since we can just say the entire connection was always using the
 WebSocket 
 protocol, and was never HTTP. 

10.1.2 101 Switching Protocols

   The server understands and is willing to comply with the client's
   request, via the Upgrade message header field (section 14.42), for a
   change in the application protocol being used on this connection. The
   server will switch protocols to those defined by the response's
   Upgrade header field immediately after the empty line which
   terminates the 101 response.


So the server has to send a response before switching. This is because
if it doesn't, how can it say 'I won't upgrade'.

-Rob



signature.asc
Description: This is a digitally signed message part


Re: Hello from Mozilla

2009-07-29 Thread Ian Hickson
On Thu, 30 Jul 2009, Robert Collins wrote:
 
 What drives the desire to live on port 80?

Nothing. WebSocket will be on ports 81 and 815. The desire to share a port 
with HTTP comes from port 443 being the only port that is usable in some 
settings due to firewalls and mitm proxies.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-29 Thread Robert Collins
On Thu, 2009-07-30 at 00:00 +, Ian Hickson wrote:
 On Thu, 30 Jul 2009, Robert Collins wrote:
  
  What drives the desire to live on port 80?
 
 Nothing. WebSocket will be on ports 81 and 815. The desire to share a port 
 with HTTP comes from port 443 being the only port that is usable in some 
 settings due to firewalls and mitm proxies.

Ok thanks. I hadn't read all the intervening messages :(.

-Rob


signature.asc
Description: This is a digitally signed message part


Re: Hello from Mozilla

2009-07-29 Thread Robert Collins
On Fri, 2009-07-17 at 10:00 +, Ian Hickson wrote:
 On Fri, 17 Jul 2009, Adrian Chadd wrote:
  2009/7/17 Ian Hickson i...@hixie.ch:
   That way you are still speaking HTTP right until the protocol 
   change occurs, so any and all HTTP compatible changes in the path(s) 
   will occur.
  
   As mentioned earlier, we need the handshake to be very precisely 
   defined because otherwise people could trick unsuspecting servers into 
   opting in, or rather appearing to opt in, and could then send all 
   kinds of commands down to those servers.
  
  Would you please provide an example of where an unsuspecting server is 
  tricked into doing something?
 
 Sure.
 
 Suppose we had no handshake at all, and that there was no data framing, so 
 that as soon as we connected to a port, we could send arbitrary data down.
 
 A Web page, say evil.example.net, could open a Web Socket connection to 
 http://www.corp.example.com/, send it a GET request for /secret-plans, and 
 then forward the contents of the file to a remote host. If they could then 
 trick someone on example.com's intranet to look at this file, and assuming 
 www.corp.example.com did nothing more than rely on connectivitity for 
 authentication (pretty common in small intranets), then evil.example.net 
 could steal the company's secret plans.

Can't the web page just send an ajax request to corp.example.com anyway?
And if it can't, why doesn't the same browser security model prevent
websockets being used in the same way?

 Now, Web Socket has a multi-layered approach to dealing with this.
 
 - there is the handshake, which requires that the server respond with a 
 very specific set of bytes, thus guaranteeing that the server is in fact 
 WebSocket-aware. Any wildcard part to this handshake increases the risk 
 that there will be a server somewhere that can be tricked. For example, if 
 the handshake were HTTP followed by anything followed by WebSocket, 
 then some HTTP servers could be tricked into doing the handshake -- for 
 example, the response to GET /WebSocket on the ietf.org host (not 
 www.ietf.org) includes the word WebSocket in the response.
 
 HTTP servers aren't the only concern, of course; we want the handshake to 
 be as secure as possible against any other protocol that may exist on any 
 server that may be deployed. We don't know what's out there (especially in 
 intranets), so the handshake has to be pretty stringent to make it as 
 unlikely as possible.

Dumping the ability to look like HTTP altogether is your best bet IMO:
even on port 443. For port 443, someone running a websocket server
should just not run an HTTPS server there. Or define port 815 as
websocket/s.

 - there is origin checking and location checking, and the location 
 checking isn't just an echo of the original request's data. This makes 
 causing the server to send back particular data harder. (It's also part of 
 our cross-origin security model and our shared hosting support; but that's 
 a separate discussion.)
 
 - there is the framing, which does provide a modicum of protection by 
 forcing another byte in front of the first author-controlled packet sent. 
 (This isn't really a security feature, it's just a lucky accident of the 
 framing that we needed to turn TCP streams into packets.)

To summarise, if I have it right, you want to make sure that *the
browser* can be sure that corp.example.com really was intending to be a
websocket server when it opened the connection. If its not, it should
bail. That seems reasonable :). We can definitely (and have been :))
advising on how to do that with HTTP, but it means *having a decent HTTP
stack*. The response to a HTTP request is always an HTTP response.
Upgrade: changes the way the wire behaves after that.


 Yes, but the client is a WebSocket client, not an HTTP client, so why 
 would it send anything but the WebSocket handshake?

Because its asking an HTTP server to upgrade. That makes it an HTTP
client and a WebSocket client... as in fact you note below ..

..
 No. I'm intending to do stuff over port 81. There is a desire in certain 
 cases to be able to share this traffic with servers running on port 80, 
 and in those cases, the content sent and the content required to be 
 returned by the server is valid HTTP until the Upgrade succeeds, at which 
 point it isn't HTTP.


  Ian, are you absolutely certain that everywhere you use the internet, 
  there is no man in the middle between you and the server you're 
  speaking to?
 
 In the case of TLS connections, yes.

In corporate networking, TLS MITM is a 'feature': company signed
certificates are used to sign the TLS connection to the corporate
firewall, and the firewall validate the SSL connection to the outside
world. I haven't personally used this, so can't really say much more
about it. Squid's ssl-bump feature can be used for this, but I believe
browser config is needed (again on a corporate basis) to tell it that
this is expected.

-Rob


signature.asc

Re: Hello from Mozilla

2009-07-17 Thread Mark Nottingham
I missed that Ian was still talking about using port 80. I think  
that's broken / more trouble than it's worth, for the reasons Adri is  
going through.


If you have to tunnel using an existing port, use 443 (with null  
encryption if you're worried about overhead, but still want to  
authenticate the endpoint). Even then, Wifi hotspots are probably  
going to redirect you, but using 443 should be a last-gasp measure  
anyway.


Cheers,


On 17/07/2009, at 3:18 PM, Adrian Chadd wrote:


2009/7/17 Ian Hickson i...@hixie.ch:

That way you are still speaking HTTP right until the protocol  
change

occurs, so any and all HTTP compatible changes in the path(s) will
occur.


As mentioned earlier, we need the handshake to be very precisely  
defined
because otherwise people could trick unsuspecting servers into  
opting in,
or rather appearing to opt in, and could then send all kinds of  
commands

down to those servers.


Would you please provide an example of where an unsuspecting server is
tricked into doing something?


Ian, don't you see and understand the semantic difference between
speaking HTTP and speaking a magic bytecode that is intended to  
look
HTTP-enough to fool a bunch of things until the upgrade process  
occurs
? Don't you understand that the possible set of things that can go  
wrong

here is quite unbounded ? Don't you understand the whole reason for
known ports and protocol descriptions in the first place?


Apparently not.


Ok. Look at this.

The byte sequence GET / HTTP/1.0\r\nHost: foo\r\nConnection:
close\r\n\r\n is not byte equivalent to the sequence GET /
HTTP/1.0\r\nConnection: close\r\nHost: foo\r\n\r\n

The same byte sequence interpreted as a HTTP protocol exchange is  
equivalent.


There's a mostly-expected understanding that what happens over port 80
is HTTP. The few cases where that has broken (specifically Shoutcast,
but I do see other crap on port 80 from time to time..) has been by
people who have implemented a mostly HTTP looking protocol, tested
that it mostly works via a few gateways/firewalls/proxies, and then
deployed it.

My suggestion is to completely toss the whole pretend to be HTTP  
thing
out of the window and look at extending or adding a new HTTP  
mechanism

for negotiating proper tunneling on port 80. If this involves making
CONNECT work on port 80 then so be it.


Redesigning HTTP is really much more work than I intend to take on  
here.
HTTP already has an Upgrade mechanism, reusing it seems the right  
thing to

do.


What you intend to take on here and what should be taken on here is
very relevant.
You're intending to do stuff over tcp/80 which looks like HTTP but
isn't HTTP. Everyone who implements anything HTTP gateway related (be
it a transparent proxy, a firewall, a HTTP router, etc) suddenly may
have to implement your websockets stuff as well. So all of a sudden
your attempt to not extend HTTP ends up extending HTTP.


The point is, there may be a whole lot of stuff going on with HTTP
implementations that you're not aware of.


Sure, but with the except of man-in-the-middle proxies, this isn't  
a big
deal -- the people implementing the server side are in control of  
what the

HTTP implementation is doing.


That may be your understanding of how the world works, but out here in
the rest of the world, the people who deploy the edge and the people
who deploy the core may not be the same people. There may be a dozen
layers of red tape, equipment lifecycle, security features, etc, that
need to be handled before websockets happy stuff can be deployed
everywhere it needs to.

Please don't discount man-in-the-middle -anything- as being easy  
to deal with.


In all cases except a man-in-the-middle proxy, this seems to be  
what we
do. I'm not sure how we can do anything in the case of such a  
proxy, since

by definition the client doesn't know it is present.


.. so you're still not speaking HTTP?

Ian, are you absolutely certain that everywhere you use the
internet, there is no man in the middle between you and the server
you're speaking to? Haven't you ever worked at any form of corporate
or enterprise environment? What about existing captive portal
deployments like wifi hotspots, some of which still use squid-2.5
(eww!) as their http firewall/proxy to control access to the internet?
That stuff is going to need upgrading sure, but I'd rather see the
upgrade happen once to a well thought out and reasonably well designed
protocol, versus having lots of little upgrades need to occur because
your HTTP but not quite HTTP exchange on port 80 isn't thought out
enough.




Adrian


--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-17 Thread Henrik Nordstrom
fre 2009-07-17 klockan 16:32 +1200 skrev Amos Jeffries:

 3.1.5.1
 Connect to the server given by /host/ on port 80 and ask it to
 upgrade from HTTP to WebSockets.
 
 The client must send only the following lines:
 
 GET /thepath/ HTTP/1.1
 Host: /host/
 Upgrade: WebSockets
 Connection: Upgrade
 
 terminated by two CRLF as per HTTP specification.

Per HTTP specifications the client SHOULD send more lines, in specific
the User-Agent.

 3.1.5.2
 A server receiving the request SHOULD ignore any other headers
 received with the request.
 
 If any data following the headers is received then fail the
 WebSocket connection. The server MUST discard any body data
 received with an Upgrade request. It MAY respond with a 4xx or
 5xx HTTP error code from the HTTP specification.

No, only 4xx. It's the request that is in error for being an WebSockets
Upgrade request, not the server.

But per HTTP specifications such body data is part of the HTTP Upgrade
request and should be ignored if switching protocols as part of ignoring
the HTTP request which contained the Upgrade request. Consider for
example if the request is a POST request, containing a alternative
simplex representation of the communication meant to be used by a
non-WebSockets server.

 3.1.5.4
 A server receiving a valid HTTP Upgrade request to WebSockets
 and which does not accept that WebSockets upgrade MUST send back
 a 4xx or 5xx HTTP response as per section 3.1.5.2.

There is no such requirement in HTTP. Handling Upgrade is purely
optional and the server is free to ignore Upgrade. Upgrade is a please
upgrade to one of these protocols if supported.

 The server SHOULD send only the following lines:
 
 HTTP/1.1 101 Web Socket Protocol Handshake
 Upgrade: WebSocket
 Connection: Upgrade

While it's true HTTP does not mandate any headers for 1xx responses,
including things like Server is a good idea in 101 responses, and there
may also be other headers required by the HTTP operation such as
Authentication-Info and possibly other headers as well in future
specifications.

Regards
Henrik



Re: Hello from Mozilla

2009-07-17 Thread Ian Hickson
On Fri, 17 Jul 2009, Amos Jeffries wrote:
 
 Um, okay. Have a read of this alternate Spec and see if you can stil 
 find the security hole you are woried about:

I don't understand in what way it substantially differs from what the spec 
says today. There are minor differences in wording, but other than that, 
and other than the requirement that two TCP connections be established to 
port 80 when using port 80 instead of just one, it seems equivalent. Could 
you elaborate on what the important difference you had in mind is?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-17 Thread Ian Hickson
On Fri, 17 Jul 2009, Adrian Chadd wrote:
 2009/7/17 Ian Hickson i...@hixie.ch:
  That way you are still speaking HTTP right until the protocol 
  change occurs, so any and all HTTP compatible changes in the path(s) 
  will occur.
 
  As mentioned earlier, we need the handshake to be very precisely 
  defined because otherwise people could trick unsuspecting servers into 
  opting in, or rather appearing to opt in, and could then send all 
  kinds of commands down to those servers.
 
 Would you please provide an example of where an unsuspecting server is 
 tricked into doing something?

Sure.

Suppose we had no handshake at all, and that there was no data framing, so 
that as soon as we connected to a port, we could send arbitrary data down.

A Web page, say evil.example.net, could open a Web Socket connection to 
http://www.corp.example.com/, send it a GET request for /secret-plans, and 
then forward the contents of the file to a remote host. If they could then 
trick someone on example.com's intranet to look at this file, and assuming 
www.corp.example.com did nothing more than rely on connectivitity for 
authentication (pretty common in small intranets), then evil.example.net 
could steal the company's secret plans.

Now, Web Socket has a multi-layered approach to dealing with this.

- there is the handshake, which requires that the server respond with a 
very specific set of bytes, thus guaranteeing that the server is in fact 
WebSocket-aware. Any wildcard part to this handshake increases the risk 
that there will be a server somewhere that can be tricked. For example, if 
the handshake were HTTP followed by anything followed by WebSocket, 
then some HTTP servers could be tricked into doing the handshake -- for 
example, the response to GET /WebSocket on the ietf.org host (not 
www.ietf.org) includes the word WebSocket in the response.

HTTP servers aren't the only concern, of course; we want the handshake to 
be as secure as possible against any other protocol that may exist on any 
server that may be deployed. We don't know what's out there (especially in 
intranets), so the handshake has to be pretty stringent to make it as 
unlikely as possible.

- there is origin checking and location checking, and the location 
checking isn't just an echo of the original request's data. This makes 
causing the server to send back particular data harder. (It's also part of 
our cross-origin security model and our shared hosting support; but that's 
a separate discussion.)

- there is the framing, which does provide a modicum of protection by 
forcing another byte in front of the first author-controlled packet sent. 
(This isn't really a security feature, it's just a lucky accident of the 
framing that we needed to turn TCP streams into packets.)


  Ian, don't you see and understand the semantic difference between 
  speaking HTTP and speaking a magic bytecode that is intended to 
  look HTTP-enough to fool a bunch of things until the upgrade process 
  occurs ? Don't you understand that the possible set of things that 
  can go wrong here is quite unbounded ? Don't you understand the whole 
  reason for known ports and protocol descriptions in the first 
  place?
 
  Apparently not.
 
 Ok. Look at this.
 
 The byte sequence GET / HTTP/1.0\r\nHost: foo\r\nConnection: 
 close\r\n\r\n is not byte equivalent to the sequence GET / 
 HTTP/1.0\r\nConnection: close\r\nHost: foo\r\n\r\n
 
 The same byte sequence interpreted as a HTTP protocol exchange is 
 equivalent.

Yes, but the client is a WebSocket client, not an HTTP client, so why 
would it send anything but the WebSocket handshake?

The only case I can see where the handshake gets changed is MITM proxies, 
but as far as I understand it, there's no way to ever get a reliable 
bidirectional non-HTTP TCP/IP connection through a Squid MITM proxy over 
port 80 to a remote server that normally acts like an HTTP server, so it 
doesn't matter anyway, since whatever we do, it won't work on that port.


 There's a mostly-expected understanding that what happens over port 80 
 is HTTP. The few cases where that has broken (specifically Shoutcast, 
 but I do see other crap on port 80 from time to time..) has been by 
 people who have implemented a mostly HTTP looking protocol, tested that 
 it mostly works via a few gateways/firewalls/proxies, and then deployed 
 it.

Is there a way to get a reliable bidirectional non-HTTP TCP/IP connection 
through a Squid MITM proxy over port 80 to a remote server that normally 
acts like an HTTP server?

If not, then sending any data over port 80 on such a network wouldn't 
work, right? So as far as I can tell, port 80 in such a scenario isn't 
relevant. Authors in such scenarios would use port 443, like Mark said.


 You're intending to do stuff over tcp/80 which looks like HTTP but isn't 
 HTTP.

No. I'm intending to do stuff over port 81. There is a desire in certain 
cases to be able to share this traffic with servers running on port 

Re: Hello from Mozilla

2009-07-17 Thread Ian Hickson
On Fri, 17 Jul 2009, Mark Nottingham wrote:

 I missed that Ian was still talking about using port 80. I think that's 
 broken / more trouble than it's worth, for the reasons Adri is going 
 through.
 
 If you have to tunnel using an existing port, use 443 (with null 
 encryption if you're worried about overhead, but still want to 
 authenticate the endpoint). Even then, Wifi hotspots are probably going 
 to redirect you, but using 443 should be a last-gasp measure anyway.

I agree -- you would only use port 80 if the network wasn't intercepting 
your requests (which you can figure out pretty quickly by just trying to 
connect, since that will fail quickly in the case of a proxy). I would 
expect uses of this protocol that don't want encryption to try port 81, 
then port 80, then port 443 with encryption, in that order; I would expect 
uses of this protocol that _do_ want encryption to just try ports 815 and 
443, in that order. 443 should always work if anything is going to work, 
as far as I can tell.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-17 Thread Henrik Nordstrom
fre 2009-07-17 klockan 10:00 + skrev Ian Hickson:

 HTTP servers aren't the only concern, of course; we want the handshake to 
 be as secure as possible against any other protocol that may exist on any 
 server that may be deployed. We don't know what's out there (especially in 
 intranets), so the handshake has to be pretty stringent to make it as 
 unlikely as possible.

The HTTP/1.x 101[...]Upgrade: WebSocket[CR][NL][...][CR][NL][CR][NL]
sequence is pretty stringent imho, without hardcoding the exact sequence
at octet level, where [...] is any sequence of ascii characters except
for [CR][NL][CR][NL]

 Yes, but the client is a WebSocket client, not an HTTP client, so why 
 would it send anything but the WebSocket handshake?

Because it's designed to also talk to a web server, and if I understand
your intended use case those clients will by nature almost certainly
also be HTTP clients, or at least embedded in HTTP clients.

 The only case I can see where the handshake gets changed is MITM proxies, 
 but as far as I understand it, there's no way to ever get a reliable 
 bidirectional non-HTTP TCP/IP connection through a Squid MITM proxy over 
 port 80 to a remote server that normally acts like an HTTP server, so it 
 doesn't matter anyway, since whatever we do, it won't work on that port.

The relevant use case you need to make sure to support in specification
is

client - HTTP Surrogate - Internal origin

don't bend over too much for transparently intercepting proxies, it's
not your job to specify how those should behave.

 Is there a way to get a reliable bidirectional non-HTTP TCP/IP connection 
 through a Squid MITM proxy over port 80 to a remote server that normally 
 acts like an HTTP server?

As I already said, generally no. But at some point transparently
intercepting Squids will have the option to switch to tunnel mode when
seeing non-HTTP traffic on port 80 (missing the HTTP signature), and at
the same time forwarding of Upgrade requests is likely to be
implemented.

 If not, then sending any data over port 80 on such a network wouldn't 
 work, right? So as far as I can tell, port 80 in such a scenario isn't 
 relevant. Authors in such scenarios would use port 443, like Mark said.

Correct.

 No. I'm intending to do stuff over port 81. There is a desire in certain 
 cases to be able to share this traffic with servers running on port 80, 
 and in those cases, the content sent and the content required to be 
 returned by the server is valid HTTP until the Upgrade succeeds, at which 
 point it isn't HTTP.

Which is the point I have been making all the time. As that is processed
by HTTP stacks your protocol need to be prepared to deal with the
aspects that the HTTP stack may introduce on you

  - HTTP authentication with it's set of status codes and HTTP headers
  - Via headers
  - Reordering of headers
  - Possible addition of Date headers in responses
  - Custom headers added to the request/response
  - And maybe other similar things as well

Up until the 101 response has finished the sequence is HTTP and if your
intention is that this should be processed by HTTP infrastructure then
you need to accept it being HTTP.

 I don't understand the relevance of your question. It doesn't matter what 
 you're talking; in the case of a MITM proxy, the client doesn't know it 
 isn't talking straight to the server. Talking HTTP more than we already do 
 doesn't suddenly mean we can get a two-way pipe set up.

Talking proper HTTP means the MITM will handle it for you assuming the
MITM can handle HTTP/1.1 properly.

Sure, Squid can not yet, and we don't claim Squid to be HTTP/1.1 either
as we don't like lying about our capabilities. But we will at some not
too distant point in time.

 I really don't understand the problem you are alluding to here. What needs 
 upgrading in such a scenario?

The company infrastructure sitting between Internet and the web
server(s) in question where some webmaster want's to deply a WebSocket
application needs to add support for the WebSocket protocol, which is
one of the primary things people who wants to run stuff like this over
port 80 want to avoid.. To them the WebSocket communication is just part
of the web application, not a separate entity which lives it's own life
requiring it's own infrastructure in firewall rules, load balancers,
servers etc.

Regards
Henrik



Re: Hello from Mozilla

2009-07-17 Thread Amos Jeffries

Henrik Nordstrom wrote:

fre 2009-07-17 klockan 16:32 +1200 skrev Amos Jeffries:


3.1.5.1
Connect to the server given by /host/ on port 80 and ask it to
upgrade from HTTP to WebSockets.

The client must send only the following lines:

GET /thepath/ HTTP/1.1
Host: /host/
Upgrade: WebSockets
Connection: Upgrade

terminated by two CRLF as per HTTP specification.


Per HTTP specifications the client SHOULD send more lines, in specific
the User-Agent.



Ah, thanks. Yes there are others that need to be added here for the 
formal draft.



3.1.5.2
A server receiving the request SHOULD ignore any other headers
received with the request.

If any data following the headers is received then fail the
WebSocket connection. The server MUST discard any body data
received with an Upgrade request. It MAY respond with a 4xx or
5xx HTTP error code from the HTTP specification.


No, only 4xx. It's the request that is in error for being an WebSockets
Upgrade request, not the server.


I'm thinking 5xx if something went wrong, same as HTTP cases. So that 
the WebSockets spec is only limiting the 'good' response, but accepting 
of any HTTP error states as also its failure state.




But per HTTP specifications such body data is part of the HTTP Upgrade
request and should be ignored if switching protocols as part of ignoring
the HTTP request which contained the Upgrade request. Consider for
example if the request is a POST request, containing a alternative
simplex representation of the communication meant to be used by a
non-WebSockets server.


Ian:  is that a relevant case? you can spec it in or out as needed.

But I'm thinking out, since the idea here is to setup a TCP-link tunnel 
then perform authentication handshake inside it. The upgrade request is 
only to get the MITM/Surrogates to pass it correctly or fail it cleanly.





3.1.5.4
A server receiving a valid HTTP Upgrade request to WebSockets
and which does not accept that WebSockets upgrade MUST send back
a 4xx or 5xx HTTP response as per section 3.1.5.2.


There is no such requirement in HTTP. Handling Upgrade is purely
optional and the server is free to ignore Upgrade. Upgrade is a please
upgrade to one of these protocols if supported.


Meaning HTTP does not care what gets returned...

 At the non-101 reply point its not usable as a WebSockets link. This 
bit is going slightly beyond HTTP in a compatible way and refers to the 
WebSockets-enabled server rejecting the socket connection.


Ian mentioned many times WebSockets being 'opt-in'. This clause permits 
'opt-in' to be denied by the server. It's irrelevant to non-WebSocket 
intermediaries and applies only to WebSocket origin servers. Perhapse 
that needs to be worded clearer.





The server SHOULD send only the following lines:

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade


While it's true HTTP does not mandate any headers for 1xx responses,
including things like Server is a good idea in 101 responses, and there
may also be other headers required by the HTTP operation such as
Authentication-Info and possibly other headers as well in future
specifications.


Ah yes. Okay.
Ian: anything else you find useful as required here as well. This is 
where you get the is the mystery server capable of WebSockets info. 
Being the _right_ one needs must separate and handled by the WebSockets 
handshake.


Just only specify it at the string level.  Specifying the order sent is 
fine but confusing because it implies order received. Specifying the 
order received beyond 101 is broken.


Amos
--
Please be using
  Current Stable Squid 2.7.STABLE6 or 3.0.STABLE16
  Current Beta Squid 3.1.0.9


Re: Hello from Mozilla

2009-07-17 Thread Amos Jeffries

Ian Hickson wrote:

On Fri, 17 Jul 2009, Amos Jeffries wrote:
Um, okay. Have a read of this alternate Spec and see if you can stil 
find the security hole you are woried about:


I don't understand in what way it substantially differs from what the spec 
says today. There are minor differences in wording, but other than that, 
and other than the requirement that two TCP connections be established to 
port 80 when using port 80 instead of just one, it seems equivalent. Could 
you elaborate on what the important difference you had in mind is?




Two connections? no. Only one. Two METHODS of possible connection.


1) CONNECT and HTTP Upgrade are optional, and independent. One may be 
used or the other. They may be both tried in any order.


2) Specific mention is made that these are for failover use ONLY after 
port 81 and 815 have both already been tried and cannot be used.


3) The specific order of bytes is not mentioned _anywhere_ in the new text.

4) The order of headers _received_ is not mentioned past the 101 / 4xx 
/5xx line. HTTP varies order in-transit.


5) Specific mention is made to ignore non-understood headers added 
randomly by intermediaries.


6) Specific mention is made to drop random extra body data sent with 
headers or request and reply and how to handle it. Fixing that 
data-feeding issue you worry about.


7) Most importantly. The WebSocket handshake is not involved in this 
section. It happens after the Upgrade shift / CONNECT tunnel / port-81 
TC link has succeeded. Not mid-way though the HTTP Upgrade processes.



Between them these differences convert your section 3.1 from a detailed 
byte-level handshake, very flaky in any non-direct port-80 link, to an 
HTTP-level handshake which can be relayed or handled properly by 
existing MITM and Surrogates.


HTTP clients and servers need very little change to operate with this as 
well and can leverage their broad base of HTTP code to process the 
headers properly and safely to the required end.


As Henrik pointed out, there are HTTP things I've overlooked in the 
quick re-write. But their addition is minor editing touchups.
HTTP Keep-Alive stuff may also be needed to encourage the WebSocket link 
to stay up long-term use for the handshake and data frames.


Amos
--
Please be using
  Current Stable Squid 2.7.STABLE6 or 3.0.STABLE16
  Current Beta Squid 3.1.0.9


Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
ons 2009-07-15 klockan 04:26 + skrev Ian Hickson:
 On Tue, 14 Jul 2009, Alex Rousskov wrote:
  
  WebSocket made the handshake bytes look like something Squid thinks it 
  understands. That is the whole point of the argument. You are sending an 
  HTTP-looking message that is not really an HTTP message. I think this is 
  a recipe for trouble, even though it might solve some problem in some 
  environments.
 
 Could you elaborate on what bytes Squid thinks it should change in the 
 WebSocket handshake?

As already mentioned HTTP specs says it MUST add a Via header element.

Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
ons 2009-07-15 klockan 07:34 + skrev Ian Hickson:
 On Wed, 15 Jul 2009, Mark Nottingham wrote:
 
  Upgrade is hop-by-hop, so it's pretty limiting.
 
 Do man-in-the-middle proxies count as a hop for the purposes of HTTP?

When used as a surrogate it does.

The transparently interceping case is outside of any specifications.

  As 
 far as I can tell from the HTTP spec, the client is supposed to know 
 whether it is speaking to a proxy or not, so man-in-the-middle proxies 
 don't affect the hop-by-hop semantics... but it's not entirely clear.

Yes, just as IP addresses are supposed to be unique and not shared or
modified in transit (NAT)...


 Sure, but that's why we have the TLS-over-port-443 option. In the cases 
 where there is uncooperative network infrastructure, the client can just 
 switch to that, and then there's no way the connection can be affected.

You think

There is a funny technique implemented at many places today which
unwinds TLS on port 443 and proxies the HTTP traffic which is supposed
to be within. Used for policy enforcement and inspection in networks
where end-to-end encrypted communication is forbidden by policy.

 Not doing so is unacceptably insecure for this use case, IMHO. We can't 
 run the risk of Web pages hitting SMTP servers and sending spam, or poking 
 at intranet servers, or who knows what else.

You still haven¨t explained how running a proper HTTP Upgrade sequence
may risk this. I just don't see it.

Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
tor 2009-07-16 klockan 01:44 + skrev Ian Hickson:

 So Squid when used as a man-in-the-middle proxy will allow arbitrary 
 traffic through port 80 if it isn't HTTP traffic?

No, but support for tunneling WebSockets can be added, but not when it
looks and feels like a HTTP message.

 This advice contradicts other advice we've gotten to the effect that if we 
 send any content over port 80, it absolutely must be HTTP-compatible.

And what we are saying is that if you make something that looks like
HTTP and runs on port 80 it should be HTTP, not just something that
looks like HTTP but isn't compatible with HTTP and which will break if
processed as if it was HTTP.

The point Amos tried to make is that if it isn't HTTP (just resembles
HTTP but isn't compatible with HTTP) then it should not look like HTTP.

For us as a proxy it's easier to deal with something that is easily
identified as not-HTTP and switch stack entirely than to try to tweak
the HTTP processing to not break looks-like-HTTP-but-isn't-HTTP
applications.

 Could you elaborate on this? Why would a transparent proxy meddle with 
 bytes after it has seen a successful Upgrade? Doesn't this contradict the 
 requirements on transparent proxies in the HTTP spec?

It won't. But it will touch the HTTP upgrade request, and possibly even
the 101 response status description.

If it at all supports Upgrade, but that is a different topic.

 For all intents and purposes, it _is_ an HTTP request. It's an Upgrade 
 request. It seems that man-in-the-middle proxies would break all Upgrades, 
 the way you've described them.

The only part of your spec we talk about here is the binary coded
looks-like-HTTP-Upgrade sequence. What happens after the
looks-like-HTTP-101-response we don't care about.

  Right down to the HTTP/1.1 reserved protocol label (do get that changed 
  please).
 
 If we're faking HTTP, then it has to look like HTTP.

And our point is DO NOT FAKE HTTP. Use HTTP.

To make the point explicit we already see one wire protocol (icecast,
used by shoutcast streaming) which uses a similar fake HTTP mechanism
like you. In this protocol the clients sends a quite well formed HTTP
request, but the response is in a slightly different protocol. When this
gets processed by an HTTP intermediary (proxy or frontend) things do
break in subtle way because the application isn't expecting the
transforms required by HTTP. For a long time noone noticed as Squid did
not conform to a specific part the HTTP specifications, but when Squid
was modified to follow HTTP specifications this application broke.


 I'm getting very mixed messages here.
 
 Is there a reliable way to open a bidirectional non-HTTP TCP/IP connection 
 through a Squid man-in-the-middle proxy over port 80 to a remote server 
 that normally acts like an HTTP server? If so, what is the sequence of 
 bytes that will act in this way?

Both yes and no.

There is experimental support available for transparent interception
operation to switch to tunnel mode when seeing non-HTTP traffic, but
this is not yet part of the official distribution (needs a bit more work
first). The use case for this is environments using transparent
interception for caching reasons but which accepts that there may be
non-HTTP applications also using port 80.

At some point we will also support switching to tunnel mode after seeing
a successful HTTP Upgrade sequence but we are not quite there yet. This
discussion is to make sure WebSockets do not break when processed via a
future Squid which do support HTTP Upgrade. The use case for this is
both transparently interception in the client network and frontend
intermediary setups in the web server network.

In a normal forward proxy environment the supported method is CONNECT,
but default policy (configuration) restricts this to port 443 and a few
other well-known SSL ports blocking port 80.

Related note to others following this discussion: Upgrade is hop-by-hop
not end-to-end.

Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
ons 2009-07-15 klockan 07:18 + skrev Ian Hickson:

 The reason we have a very strict handshake is because we don't want it to 
 be possible to trick a non-WebSocket-aware server into accepting a 
 connection (or similarly, having the client be tricked by the script into 
 accepting a connection to a non-WebSocket-aware server). This is 
 especially important for WebSockets because once there's a connection 
 established, any data might be sent.

Doesn't need to be octet-level strict for that. If you get a 101
response you know it's been accepted.

If you get anything else you need to deal with that, as required by
HTTP. 

Until the end of the 101 response it's all HTTP, per the rules of HTTP.

 HTTP is getting similar restrictions, by the way, in the form of the CORS 
 mechanism. Without CORS, scripts can't ever read data back from cross-site 
 HTTP requests they initiate. CORS allows the server to opt in to sending 
 data back to a third-party script.

Which is fine, as the HTTP part of CORS is a simple HTTP extension
within the framework defined by HTTP.

And I wouldn't call it that HTTP gets restrictions. In the case of CORS
HTTP is extended to give client scripts authorization to access the
servers data where such scripts before could not due to access
restrictions implemented in the user-agent.

For others following this thread:
http://www.w3.org/TR/access-control/
http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/


Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
ons 2009-07-15 klockan 18:39 +1200 skrev Amos Jeffries:
 Byte 5 through to the first of: two CRLF or one NULL byte. Specified as
 step 1 through 11 by the looks of it.
 
 Correctly operating:
  * MUST remove the Upgrade: WebSocket\r\n bytes.

Yes/No depending on the context. If a normal forward proxy sees such
request then yes, but that's outside WebSocket specification as CONNECT
is used in such case.

In a surrogate intermediary situation it's essentially up to us how we
deal with the upgrade. The operations of surrogate-origin is outside
of HTTP specifications. Specifications only cover client-surrogate in
such setups.

In a transparent intercepting proxy it's our responsibility to deal with
the Upgrade as appropriate. i.e. switch to tunnel mode, or declare it
not supported by removing the header. Transparent interception mode is
outside of HTTP specifications.

  * MUST add Via: 1.1  followed by an arbitrary length and content string.

Yes.

  * SHOULD add a Date: header (position optional, suggested to be between
 GET and Host:).

No. The Date requirement is only on responses, not requests.

 Conditionally:
  * Depending on the local network topology _sometimes_ proxies required to
 alter the section labeled the path in order for the request to even
 happen. Changing it from ( / path ) to ( http://; hostname / path )

Yes, but it will get changed back to the simple /path form before the
requests hits an actual origin server.

  ** The http://hostname part MAY be removed again before passing to Server.
 Usually not.

It MUST be removed per HTTP specifications (but servers MUST accept it
if sent). Future HTTP specifications MAY be relaxed to allow
absolute-URI form to be sent in requests as well but that's future when
HTTP/1.0 servers is confirmed gone from the globe.

 To raise the extreme end of the problem:
   In HTTP a proxy MAY go so far as to sort the headers alphabetically and
 expect things to still work well.

Yes.

 The solutions you need to be looking at are:
  * using HTTP Upgrade as per the HTTP spec, with full flexibility.
  * using ports other than 80.
  * sending requests as pure binary and dropping the HTTP look-alike bits

Yes.

Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Henrik Nordstrom
tor 2009-07-16 klockan 23:11 +1200 skrev Amos Jeffries:

 The faux-request begins with: GET /path-bytes HTTP/1.1
 It also contains Connection: Upgrade.

Only when not talking to a proxy. If a proxy is configured CONNECT is
used for setting up a tunnel first. See 3.1 Handshake, step 3.

 For peers we already have the tricky case where admin may not set 
 'originserver' on web server links to trigger the un-map.
 Apache et al are compliant enough for this not to break the HTTP, but 
 will completely break the WebSocket faux-HTTP byte-wise spec.

True, but my point is that such setups is NOT HTTP/1.1 compliant.

In HTTP/1.1 requests to origin server MUST be sent without the
scheme://[u...@]host:port part, and servers MUST accept both forms.

Regards
Henrik



Re: Hello from Mozilla

2009-07-16 Thread Mark Nottingham
Realise that server-side infrastructure often includes things like  
CDNs (even when the content is uncacheable), reverse proxies and L7  
load balancers -- all of which can make the changes we're talking about.


While it's true that these things are under control of the people who  
own the server, changing them is *much* harder than deploying an  
Apache module.


Cheers,


On 17/07/2009, at 9:53 AM, Ian Hickson wrote:



The point is, there may be a whole lot of stuff going on with HTTP
implementations that you're not aware of.


Sure, but with the except of man-in-the-middle proxies, this isn't a  
big
deal -- the people implementing the server side are in control of  
what the

HTTP implementation is doing.



--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-16 Thread Mark Nottingham
Yep. Just think it's worth pointing out in the draft, since you go to  
such efforts to make this possible.


Cheers,


On 17/07/2009, at 10:28 AM, Ian Hickson wrote:


On Fri, 17 Jul 2009, Mark Nottingham wrote:


Realise that server-side infrastructure often includes things like  
CDNs

(even when the content is uncacheable), reverse proxies and L7 load
balancers -- all of which can make the changes we're talking about.

While it's true that these things are under control of the people who
own the server, changing them is *much* harder than deploying an  
Apache

module.


People with that level of complexity can easily just not share the  
port.


--
Ian Hickson   U+1047E) 
\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _ 
\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'-- 
(,_..'`-.;.'


--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-16 Thread Ian Hickson
On Fri, 17 Jul 2009, Mark Nottingham wrote:
 On 17/07/2009, at 10:28 AM, Ian Hickson wrote:
  On Fri, 17 Jul 2009, Mark Nottingham wrote:
   
   Realise that server-side infrastructure often includes things like 
   CDNs (even when the content is uncacheable), reverse proxies and L7 
   load balancers -- all of which can make the changes we're talking 
   about.
   
   While it's true that these things are under control of the people 
   who own the server, changing them is *much* harder than deploying an 
   Apache module.
  
  People with that level of complexity can easily just not share the 
  port.

 Yep. Just think it's worth pointing out in the draft, since you go to 
 such efforts to make this possible.

Done.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-16 Thread Adrian Chadd
2009/7/17 Ian Hickson i...@hixie.ch:

 That way you are still speaking HTTP right until the protocol change
 occurs, so any and all HTTP compatible changes in the path(s) will
 occur.

 As mentioned earlier, we need the handshake to be very precisely defined
 because otherwise people could trick unsuspecting servers into opting in,
 or rather appearing to opt in, and could then send all kinds of commands
 down to those servers.

Would you please provide an example of where an unsuspecting server is
tricked into doing something?

 Ian, don't you see and understand the semantic difference between
 speaking HTTP and speaking a magic bytecode that is intended to look
 HTTP-enough to fool a bunch of things until the upgrade process occurs
 ? Don't you understand that the possible set of things that can go wrong
 here is quite unbounded ? Don't you understand the whole reason for
 known ports and protocol descriptions in the first place?

 Apparently not.

Ok. Look at this.

The byte sequence GET / HTTP/1.0\r\nHost: foo\r\nConnection:
close\r\n\r\n is not byte equivalent to the sequence GET /
HTTP/1.0\r\nConnection: close\r\nHost: foo\r\n\r\n

The same byte sequence interpreted as a HTTP protocol exchange is equivalent.

There's a mostly-expected understanding that what happens over port 80
is HTTP. The few cases where that has broken (specifically Shoutcast,
but I do see other crap on port 80 from time to time..) has been by
people who have implemented a mostly HTTP looking protocol, tested
that it mostly works via a few gateways/firewalls/proxies, and then
deployed it.

 My suggestion is to completely toss the whole pretend to be HTTP thing
 out of the window and look at extending or adding a new HTTP mechanism
 for negotiating proper tunneling on port 80. If this involves making
 CONNECT work on port 80 then so be it.

 Redesigning HTTP is really much more work than I intend to take on here.
 HTTP already has an Upgrade mechanism, reusing it seems the right thing to
 do.

What you intend to take on here and what should be taken on here is
very relevant.
You're intending to do stuff over tcp/80 which looks like HTTP but
isn't HTTP. Everyone who implements anything HTTP gateway related (be
it a transparent proxy, a firewall, a HTTP router, etc) suddenly may
have to implement your websockets stuff as well. So all of a sudden
your attempt to not extend HTTP ends up extending HTTP.

 The point is, there may be a whole lot of stuff going on with HTTP
 implementations that you're not aware of.

 Sure, but with the except of man-in-the-middle proxies, this isn't a big
 deal -- the people implementing the server side are in control of what the
 HTTP implementation is doing.

That may be your understanding of how the world works, but out here in
the rest of the world, the people who deploy the edge and the people
who deploy the core may not be the same people. There may be a dozen
layers of red tape, equipment lifecycle, security features, etc, that
need to be handled before websockets happy stuff can be deployed
everywhere it needs to.

Please don't discount man-in-the-middle -anything- as being easy to deal with.

 In all cases except a man-in-the-middle proxy, this seems to be what we
 do. I'm not sure how we can do anything in the case of such a proxy, since
 by definition the client doesn't know it is present.

.. so you're still not speaking HTTP?

Ian, are you absolutely certain that everywhere you use the
internet, there is no man in the middle between you and the server
you're speaking to? Haven't you ever worked at any form of corporate
or enterprise environment? What about existing captive portal
deployments like wifi hotspots, some of which still use squid-2.5
(eww!) as their http firewall/proxy to control access to the internet?
That stuff is going to need upgrading sure, but I'd rather see the
upgrade happen once to a well thought out and reasonably well designed
protocol, versus having lots of little upgrades need to occur because
your HTTP but not quite HTTP exchange on port 80 isn't thought out
enough.




Adrian


Re: Hello from Mozilla

2009-07-15 Thread Adrian Chadd
2009/7/15 Ian Hickson i...@hixie.ch:
 On Tue, 14 Jul 2009, Alex Rousskov wrote:

 WebSocket made the handshake bytes look like something Squid thinks it
 understands. That is the whole point of the argument. You are sending an
 HTTP-looking message that is not really an HTTP message. I think this is
 a recipe for trouble, even though it might solve some problem in some
 environments.

 Could you elaborate on what bytes Squid thinks it should change in the
 WebSocket handshake?

Anything which it can under the HTTP/1.x RFCs.

Maybe I missed it - why exactly again aren't you just talking HTTP on
the HTTP port(s), and doing a standard HTTP upgrade?


Adrian


Re: Hello from Mozilla

2009-07-15 Thread Mark Nottingham

Upgrade is hop-by-hop, so it's pretty limiting.

Ian, an example:

An intermediary (transparent, intercepting or whatever) can and often  
does add arbitrary headers; e.g., x-forwarded-for. This is completely  
legal in HTTP, where headers that are not understood are ignored, and  
additionally several headers have provisions to change values in  
headers as well (e.g., transfer-encoding, te, via, connection).


They're also allowed to change the formatting of the message; e.g., re- 
wrap headers, normalise whitespace.


Specifying a bit-for bit handshake is incredibly fragile.

Cheers,


On 15/07/2009, at 3:26 PM, Adrian Chadd wrote:


2009/7/15 Ian Hickson i...@hixie.ch:

On Tue, 14 Jul 2009, Alex Rousskov wrote:


WebSocket made the handshake bytes look like something Squid  
thinks it
understands. That is the whole point of the argument. You are  
sending an
HTTP-looking message that is not really an HTTP message. I think  
this is
a recipe for trouble, even though it might solve some problem in  
some

environments.


Could you elaborate on what bytes Squid thinks it should change in  
the

WebSocket handshake?


Anything which it can under the HTTP/1.x RFCs.

Maybe I missed it - why exactly again aren't you just talking HTTP on
the HTTP port(s), and doing a standard HTTP upgrade?


Adrian


--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-15 Thread Amos Jeffries
On Wed, 15 Jul 2009 04:26:42 + (UTC), Ian Hickson i...@hixie.ch wrote:
 On Tue, 14 Jul 2009, Alex Rousskov wrote:
 
 WebSocket made the handshake bytes look like something Squid thinks it 
 understands. That is the whole point of the argument. You are sending an

 HTTP-looking message that is not really an HTTP message. I think this is

 a recipe for trouble, even though it might solve some problem in some 
 environments.
 
 Could you elaborate on what bytes Squid thinks it should change in the 
 WebSocket handshake?

Byte 5 through to the first of: two CRLF or one NULL byte. Specified as
step 1 through 11 by the looks of it.

Correctly operating:
 * MUST remove the Upgrade: WebSocket\r\n bytes.
 * MUST add Via: 1.1  followed by an arbitrary length and content string.
 * SHOULD add a Date: header (position optional, suggested to be between
GET and Host:).
   Though Squid does not (yet) do this, other proxies and future fully HTTP
compliant Squid might.

Conditionally:
 * Depending on the local network topology _sometimes_ proxies required to
alter the section labeled the path in order for the request to even
happen. Changing it from ( / path ) to ( http://; hostname / path )
 ** The http://hostname part MAY be removed again before passing to Server.
Usually not.


To raise the extreme end of the problem:
  In HTTP a proxy MAY go so far as to sort the headers alphabetically and
expect things to still work well.


The solutions you need to be looking at are:
 * using HTTP Upgrade as per the HTTP spec, with full flexibility.
 * using ports other than 80.
 * sending requests as pure binary and dropping the HTTP look-alike bits


Amos



Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Adrian Chadd wrote:
 2009/7/15 Ian Hickson i...@hixie.ch:
  On Tue, 14 Jul 2009, Alex Rousskov wrote:
 
  WebSocket made the handshake bytes look like something Squid thinks it
  understands. That is the whole point of the argument. You are sending an
  HTTP-looking message that is not really an HTTP message. I think this is
  a recipe for trouble, even though it might solve some problem in some
  environments.
 
  Could you elaborate on what bytes Squid thinks it should change in the
  WebSocket handshake?
 
 Anything which it can under the HTTP/1.x RFCs.

Could you give some examples? What part of the handshake would Squid 
change?


 Maybe I missed it - why exactly again aren't you just talking HTTP on 
 the HTTP port(s), and doing a standard HTTP upgrade?

WebSocket isn't an HTTP protocol, or subprotocol, it's an independant 
protocol. The only reason we have an HTTP-Upgrade-like mechanism at all is 
so that people who want to can share a port with an HTTP server.

(i.e. WebSocket doesn't use a standard HTTP Upgrade for the same reason 
FTP doesn't.)

The reason we have a very strict handshake is because we don't want it to 
be possible to trick a non-WebSocket-aware server into accepting a 
connection (or similarly, having the client be tricked by the script into 
accepting a connection to a non-WebSocket-aware server). This is 
especially important for WebSockets because once there's a connection 
established, any data might be sent.

HTTP is getting similar restrictions, by the way, in the form of the CORS 
mechanism. Without CORS, scripts can't ever read data back from cross-site 
HTTP requests they initiate. CORS allows the server to opt in to sending 
data back to a third-party script.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Mark Nottingham wrote:

 Upgrade is hop-by-hop, so it's pretty limiting.

Do man-in-the-middle proxies count as a hop for the purposes of HTTP? As 
far as I can tell from the HTTP spec, the client is supposed to know 
whether it is speaking to a proxy or not, so man-in-the-middle proxies 
don't affect the hop-by-hop semantics... but it's not entirely clear.


 Ian, an example:
 
 An intermediary (transparent, intercepting or whatever) can and often 
 does add arbitrary headers; e.g., x-forwarded-for. This is completely 
 legal in HTTP, where headers that are not understood are ignored, and 
 additionally several headers have provisions to change values in headers 
 as well (e.g., transfer-encoding, te, via, connection).
 
 They're also allowed to change the formatting of the message; e.g., 
 re-wrap headers, normalise whitespace.

Sure, but that's why we have the TLS-over-port-443 option. In the cases 
where there is uncooperative network infrastructure, the client can just 
switch to that, and then there's no way the connection can be affected.


 Specifying a bit-for bit handshake is incredibly fragile.

Not doing so is unacceptably insecure for this use case, IMHO. We can't 
run the risk of Web pages hitting SMTP servers and sending spam, or poking 
at intranet servers, or who knows what else.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Amos Jeffries wrote:
  
  Could you elaborate on what bytes Squid thinks it should change in the 
  WebSocket handshake?
 
 Byte 5 through to the first of: two CRLF or one NULL byte. Specified as
 step 1 through 11 by the looks of it.
 
 Correctly operating:
  * MUST remove the Upgrade: WebSocket\r\n bytes.
 [...]

This would cause the WebSocket connection to fail, which is the correct 
behaviour. After all, if the connection isn't upgraded, we don't want 
anything further to happen (in particular we don't want the client sending 
arbitrary bytes to the server or proxy, since that would open up the proxy 
to being abused to download content from any arbitrary server including 
intranet servers or other domains on shared-hosting servers).

So loosening up the handshake wouldn't solve the problem described 
previously of Squid breaking an HTTP Upgrade to WebSocket in the case of a 
client behind a firewall that only allows port 80 and where all traffic 
through that port goes through a man-in-the-middle proxy.

What solution would you recommend for such a case?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Mark Nottingham

On 15/07/2009, at 5:34 PM, Ian Hickson wrote:


On Wed, 15 Jul 2009, Mark Nottingham wrote:


Upgrade is hop-by-hop, so it's pretty limiting.


Do man-in-the-middle proxies count as a hop for the purposes of  
HTTP? As

far as I can tell from the HTTP spec, the client is supposed to know
whether it is speaking to a proxy or not, so man-in-the-middle proxies
don't affect the hop-by-hop semantics... but it's not entirely clear.


Intercepting (often called transparent, although that's confusing  
because HTTP defines semantically transparent as something  
completely different) do consider them to be separate hops (to be  
clear, the hops are on the wire, not on the devices, although  
sometimes there might be a virtual hop inside a device).


There are a few L7 load balancers that don't act as a full  
intermediary in the HTTP sense (or at least, what they do is muddy  
enough that it's not clear), but do fiddle with headers (e.g., this is  
why you see things like Coenection instead of Connection).


The important thing to remember is that interception *only* happens on  
port 80, except in the most pathological of networks (and you won't be  
able to do anything about them anyway).


Notice that I'm making a distinction between intercepting and  
firewalling here; all bets are off when a firewall does stateful  
inspection of your protocol, unless you can convince it to pass an  
encrypted stream (the TLS-over-443 solution).




They're also allowed to change the formatting of the message; e.g.,
re-wrap headers, normalise whitespace.


Sure, but that's why we have the TLS-over-port-443 option. In the  
cases
where there is uncooperative network infrastructure, the client can  
just
switch to that, and then there's no way the connection can be  
affected.


As long as you're using TLS, yes. That's going to limit scaling, of  
course.




Specifying a bit-for bit handshake is incredibly fragile.


Not doing so is unacceptably insecure for this use case, IMHO. We  
can't
run the risk of Web pages hitting SMTP servers and sending spam, or  
poking

at intranet servers, or who knows what else.



Let me put that a slightly different way; specifying a bit-for-bit  
handshake is fragile *when you expect it to pass through HTTP  
infrastructure that has no reason to preserve those bits exactly as  
they are*.


Can you remind me why you need the handshake to look like valid HTTP  
again? I think that's the crux here.


Cheers,

--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Mark Nottingham wrote:
 
 Can you remind me why you need the handshake to look like valid HTTP 
 again? I think that's the crux here.

Because in some cases, people will want to share the same port for their 
HTTP server as for their WebSocket server. For example, if they want to do 
TLS-WebSocket-over-port-443, in the case where that host also has an HTTPS 
server on port 443.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Amos Jeffries

Ian Hickson wrote:

On Wed, 15 Jul 2009, Amos Jeffries wrote:
Could you elaborate on what bytes Squid thinks it should change in the 
WebSocket handshake?

Byte 5 through to the first of: two CRLF or one NULL byte. Specified as
step 1 through 11 by the looks of it.

Correctly operating:
 * MUST remove the Upgrade: WebSocket\r\n bytes.
[...]


This would cause the WebSocket connection to fail, which is the correct 
behaviour. After all, if the connection isn't upgraded, we don't want 
anything further to happen (in particular we don't want the client sending 
arbitrary bytes to the server or proxy, since that would open up the proxy 
to being abused to download content from any arbitrary server including 
intranet servers or other domains on shared-hosting servers).


So loosening up the handshake wouldn't solve the problem described 
previously of Squid breaking an HTTP Upgrade to WebSocket in the case of a 
client behind a firewall that only allows port 80 and where all traffic 
through that port goes through a man-in-the-middle proxy.


What solution would you recommend for such a case?



a) Getting a dedicated WebSocket port assigned.
   * You and the client needing it have an argument to get that port 
opened through the firewall.
   * Squid and other proxies can be altered to allow CONNECT through to 
safe defined ports (80 is not one). Or to do the WebSocket upgrade itself.


b) accepting that the network being traversed is screwed beyond 
redemption by its own policy or admin.



Amos
--
Please be using
  Current Stable Squid 2.7.STABLE6 or 3.0.STABLE16
  Current Beta Squid 3.1.0.9


Re: Hello from Mozilla

2009-07-15 Thread Adrian Chadd
2009/7/15 Amos Jeffries squ...@treenet.co.nz:

 a) Getting a dedicated WebSocket port assigned.
   * You and the client needing it have an argument to get that port opened
 through the firewall.
   * Squid and other proxies can be altered to allow CONNECT through to safe
 defined ports (80 is not one). Or to do the WebSocket upgrade itself.

 b) accepting that the network being traversed is screwed beyond redemption
 by its own policy or admin.

I think the fundamental mistake being made here by Ian (and
potentially others) is breaking the assumption that specific protocols
exist on the well-known ports. Suddenly treating stuff on port 80 as
almost but not quite HTTP is bound to cause issues, both devices
speaking valid HTTP (eg Squid) and firewalls etc which may treat the
exchange as not HTTP and decide to start dropping things. Or worse -
passing it through, sort of.

Ian - I understand your motivations here but I think it shows a
fundamental mis-understanding of the glue which keeps the internet
mostly functioning together. Here's a question for you - would you run
a mythical protocol, call it foonet, over IP, if it looked
almost-but-not-quite like IP so people could run it on their existing
IP networks? Can you see any particular issues with that? Other slots
in the mythical OSI stack shouldn't be treated any differently.


Adrian


Re: Hello from Mozilla

2009-07-15 Thread Alex Rousskov
On 07/15/2009 01:59 AM, Ian Hickson wrote:
 On Wed, 15 Jul 2009, Mark Nottingham wrote:
 Can you remind me why you need the handshake to look like valid HTTP 
 again? I think that's the crux here.
 
 Because in some cases, people will want to share the same port for their 
 HTTP server as for their WebSocket server. For example, if they want to do 
 TLS-WebSocket-over-port-443, in the case where that host also has an HTTPS 
 server on port 443.

Can such a dual-purpose port-sharing server implement both HTTP and
WebSocket stacks and use the right stack depending on the first byte[s]
of the incoming message? If port sharing is the primary motivation here,
then dual protocol stack support seems like the right solution.

This can be even implemented as a dumb TCP-level switch application
that connects to either an HTTP server or a WebSocket server behind it.
No binary HTTP messages, no risk of HTTP intermediaries screwing up
with the not-really-HTTP-but-looking-like-one traffic. Just two
completely different protocols sharing the same port.

HTH,

Alex.


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Thu, 16 Jul 2009, Amos Jeffries wrote:
  
  What solution would you recommend for such a case?
 
 a) Getting a dedicated WebSocket port assigned.

The plan is to ask for ports 81 and 815.


* You and the client needing it have an argument to get that port opened
 through the firewall.
* Squid and other proxies can be altered to allow CONNECT through to safe
 defined ports (80 is not one). Or to do the WebSocket upgrade itself.

On the long term, that is the expected solution, yes. It doesn't work on 
the short term, though.


 b) accepting that the network being traversed is screwed beyond 
 redemption by its own policy or admin.

That's not really a solution.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Adrian Chadd wrote:
 
 I think the fundamental mistake being made here by Ian (and potentially 
 others) is breaking the assumption that specific protocols exist on the 
 well-known ports. Suddenly treating stuff on port 80 as almost but not 
 quite HTTP is bound to cause issues, both devices speaking valid HTTP 
 (eg Squid) and firewalls etc which may treat the exchange as not HTTP 
 and decide to start dropping things. Or worse - passing it through, 
 sort of.

WebSocket really is its own protocol with its own ports. The talk about 
port 80 is only because in some environments, those other ports aren't 
going to work, and so there is interest in tunneling over ports 80 and 
443, and this means sharing with HTTP servers, hence the Upgrade dance.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Wed, 15 Jul 2009, Alex Rousskov wrote:
 On 07/15/2009 01:59 AM, Ian Hickson wrote:
  On Wed, 15 Jul 2009, Mark Nottingham wrote:
  Can you remind me why you need the handshake to look like valid HTTP 
  again? I think that's the crux here.
  
  Because in some cases, people will want to share the same port for their 
  HTTP server as for their WebSocket server. For example, if they want to do 
  TLS-WebSocket-over-port-443, in the case where that host also has an HTTPS 
  server on port 443.
 
 Can such a dual-purpose port-sharing server implement both HTTP and 
 WebSocket stacks and use the right stack depending on the first byte[s] 
 of the incoming message?

Isn't that exactly what an HTTP Upgrade is?


 If port sharing is the primary motivation here, then dual protocol stack 
 support seems like the right solution.
 
 This can be even implemented as a dumb TCP-level switch application 
 that connects to either an HTTP server or a WebSocket server behind it. 
 No binary HTTP messages, no risk of HTTP intermediaries screwing up 
 with the not-really-HTTP-but-looking-like-one traffic. Just two 
 completely different protocols sharing the same port.

That's exactly what WebSocket is doing.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Thu, 16 Jul 2009, Mark Nottingham wrote:

 As an alternative, why not:
 
 1) specify a new port for normal WebSocket operation, and
 2) specify that if there's a proxy configured, ask the proxy to CONNECT to
 your new port, and
 3) specify that if #2 fails, they can CONNECT to 443 and ask for an Upgrade to
 WebSockets in the first HTTP request.

We don't want to ever have a spec-mandated switch from port to port (since 
that implies an origin change), but basically, that's what the spec 
currently says, except it requires the script to detect the failure at #2 
and requires the script to explicitly try again on port 443. (And except 
that the Upgrade has to be precisely constrained, not arbitrary HTTP, so 
that we never get to a situation where the client thinks it has done an 
upgrade but really the other side was tricked into sending the right bytes 
for that, letting the script speak to a poor unsuspecting server that 
didn't intentionally opt in.)

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-15 Thread Mark Nottingham


On 16/07/2009, at 12:28 PM, Ian Hickson wrote:


On Thu, 16 Jul 2009, Mark Nottingham wrote:


As an alternative, why not:

1) specify a new port for normal WebSocket operation, and
2) specify that if there's a proxy configured, ask the proxy to  
CONNECT to

your new port, and
3) specify that if #2 fails, they can CONNECT to 443 and ask for an  
Upgrade to

WebSockets in the first HTTP request.


We don't want to ever have a spec-mandated switch from port to port  
(since

that implies an origin change),


Ah - that makes sense.


but basically, that's what the spec
currently says, except it requires the script to detect the failure  
at #2
and requires the script to explicitly try again on port 443. (And  
except
that the Upgrade has to be precisely constrained, not arbitrary  
HTTP, so
that we never get to a situation where the client thinks it has done  
an
upgrade but really the other side was tricked into sending the right  
bytes

for that, letting the script speak to a poor unsuspecting server that
didn't intentionally opt in.)


So, to be clear, the only time the byte-for-byte HTTP handshake is  
used is when it's over a TLS tunnel via CONNECT (i.e., it's not used  
to set up the tunnel, but only once it's established)?


If that's the case, should be no problem. A bit weird, thought;  
speaking two protocols on the same port isn't really good practice...


Cheers,

--
Mark Nottingham   m...@yahoo-inc.com




Re: Hello from Mozilla

2009-07-15 Thread Ian Hickson
On Thu, 16 Jul 2009, Mark Nottingham wrote:
 
 So, to be clear, the only time the byte-for-byte HTTP handshake is used 
 is when it's over a TLS tunnel via CONNECT (i.e., it's not used to set 
 up the tunnel, but only once it's established)?

It's used whenever the client thinks it has a connection to the 
destination HTTP or WebSocket server, whether that's over TLS or not.

If it _knows_ that it is talking to a proxy, then it does the CONNECT 
thing first (or whatever is appropriate; SOCKS proxies are preferred).

If it thinks it is talking to the destination server but is being 
intercepted by a man-in-the-middle proxy, e.g. when it tries to connect 
over port 80 without knowing of any proxies (not a recommended practice, 
but it could happen), then you run into the problem that Adrian and I are 
discussing in the separate branch of this thread.


 If that's the case, should be no problem. A bit weird, thought; speaking 
 two protocols on the same port isn't really good practice...

Indeed, that's why it has (well, will have, they're not registered yet) 
its own ports. On the long term, I would hope that we could just use 
those, and not have to worry about HTTP at all. We're not there yet.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-14 Thread Henrik Nordstrom
tor 2009-07-02 klockan 17:59 -0700 skrev Jason Duell:

 1) I have a quick question about the limitations that you put by
 default on the CONNECT method.  squid.conf contains
 
 # Deny CONNECT to other than SSL ports
 http_access deny CONNECT !SSL_ports
 
 So squid by default only allows CONNECT to port 443.   I assume this
 is a rule-of-thumb security measure, since you figured that port 443
 is the only common legitimate case for CONNECT?   How long has this
 been the default behavior?  Do you know if other proxy servers out
 there also do this?

As you already know it's a security measure. I would expect it to be
implemented by quite many as it's mentioned in the original Netscape
document where CONNECT was first specified. I am not sure if Netscape
still has that document, but it was later published as an internet-draft

http://tools.ietf.org/html/draft-luotonen-ssl-tunneling-03

Due to this fact, the proxy cannot verify that the protocol
being spoken is really SSL, and so the proxy configuration
should explicitly limit allowed connections to well-known SSL
ports (such as 443 for HTTPS, 563 for SNEWS, as assigned by the
Internet Assigned Numbers Authority).

When CONNECT later entered HTTP standards-track via the TLS working
group it was for a slightly different model however (HTTP/1.1 Upgrade
mechanism), and that text ONLY talks about port 80 and the security
risks of allowing other ports.

http://tools.ietf.org/html/rfc2817#section-8.2

A generic TCP tunnel is fraught with security risks. First, such
authorization should be limited to a small number of known
ports. The Upgrade: mechanism defined here only requires onward
tunneling at port 80. Second, since tunneled data is opaque to
the proxy, there are additional risks to tunneling to other
well-known or reserved ports. A putative HTTP client CONNECTing
to port 25 could relay spam via SMTP, for example.


And the HTTP Upgrade mechanism generally haven't taken off yet with most
of the net stuck in the https model, so there haven't been much (any
before you) demands for CONNECT to port 80.

 I noticed that in section 3.1.3 the spec relies implicitly on CONNECT
 being allowed to arbitrary ports.  But this is not the case for
 default installs of squid, and thus I fear that the general approach
 may be flawed.

As you can see above all specifications available for the CONNECT method
recommends very strict rules regarding which ports is allowed.

 I suppose we could ask that you allow arbitrary CONNECT access (or at
 least to the well-known websockets ports: 80/81/815).  But I'm
 guessing that wouldn't help much, as it would probably take many years
 for that change to roll out across the net.

Indeed. And as discussed we would never ship a default config which
allows arbitrary ports, just a carefully selected list of ports.

For what it's worth neither 81 or 815 is registered with IANA, and the
web-sockets draft you referenced has expired. 

Regards
Henrik



Re: Hello from Mozilla

2009-07-14 Thread Henrik Nordstrom
tis 2009-07-14 klockan 23:35 +0200 skrev Henrik Nordstrom:

 For what it's worth neither 81 or 815 is registered with IANA, and the
 web-sockets draft you referenced has expired. 

Correction, the draft is not expired as it was recently resubmitted to
IETF, but very much a work in progress. 

The correct link for reading up on websockets is

http://dev.w3.org/html5/websockets/

and/or

http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol


There was a very brief discussion regarding websockets in the HTTPbis
IETF WG in January. But it didn't spur very much interest among the HTTP
people and discussions quickly died, not too surprisingly as it's not
HTTP even if the initial connection setup is wrapped in an HTTP style
message to be able to piggy-back on port 80.

http://lists.w3.org/Archives/Public/ietf-http-wg/2009JanMar/0008.html

The actual discussions regarding this family of wire protocols now take
place on the HYBI IETF mailing list

https://www.ietf.org/mailman/listinfo/hybi

and from a quick scan of the discussions there apparently is several
(two to four) proposals being discussed.

and it's still very early to say where things will end up. There is not
yet an official IETF working group dealing with this, just an informal
gathering to discuss the problem area to see in what direction an
eventual standardization effort should go.

Regards
Henrik



Re: Hello from Mozilla

2009-07-14 Thread Henrik Nordstrom
ons 2009-07-08 klockan 07:00 + skrev Ian Hickson:

 Well, the client is a WebSocket client, so it can always generate the 
 exact byte sequence specified in the spec almost by definition. The server 
 side is restrictive, but should be implementable without too much trouble 
 so long as there is a way to register a protocol handler that can prevent 
 the HTTP side of the server from sending any bytes at all as part of the 
 response. I agree that this is suboptimal, but we're somewhat forced into 
 this by one of our security design requirements (that the handshake be 
 very specific to avoid enabling request smuggling or other such behaviour 
 -- basically we really want to be sure we're talking to a WebSocket server 
 at the end of the handshake).

If you use HTTP Upgrade as the initial handshake mechanism and expect
this to be layered ontop of HTTP servers then you SHOULD use HTTP for
this sequence. What takes place after the HTTP/1.1 response to the
Upgrade is entirely yours, but until then it's HTTP. Hardcoding this
sequence is just silly, and will cause a lot of trouble later on.

You already touch some aspects of HTTP such as authentication. Now throw
things like NTLM or Digest authentication into the mix and you will
quickly find that the current specification is a bit too limiting if the
intention is that the upgrade requests should be processed by an HTTP
server.

Also regarding HTTP Upgrade semantics. If you want to follow that model
then there is not really any relation between the initial Upgrade
request and what takes place after the upgrade has completed. It's a
complete switch of protocols, with their own semantics. 

Regards
Henrik



Re: Hello from Mozilla

2009-07-14 Thread Alex Rousskov
On 07/14/2009 04:38 PM, Henrik Nordstrom wrote:
 ons 2009-07-08 klockan 07:00 + skrev Ian Hickson:
 
 Well, the client is a WebSocket client, so it can always generate the 
 exact byte sequence specified in the spec almost by definition. The server 
 side is restrictive, but should be implementable without too much trouble 
 so long as there is a way to register a protocol handler that can prevent 
 the HTTP side of the server from sending any bytes at all as part of the 
 response. I agree that this is suboptimal, but we're somewhat forced into 
 this by one of our security design requirements (that the handshake be 
 very specific to avoid enabling request smuggling or other such behaviour 
 -- basically we really want to be sure we're talking to a WebSocket server 
 at the end of the handshake).
 
 If you use HTTP Upgrade as the initial handshake mechanism and expect
 this to be layered ontop of HTTP servers then you SHOULD use HTTP for
 this sequence. What takes place after the HTTP/1.1 response to the
 Upgrade is entirely yours, but until then it's HTTP. Hardcoding this
 sequence is just silly, and will cause a lot of trouble later on.

I strongly agree with this. Frankly, I suspect (hope?) that IETF gurus
would prevent publishing an RFC that kind of reuses the HTTP Upgrade
mechanism but then declares many compliant Upgrade exchanges invalid.

If you think your approach is the right one, I would suggest openly
discussing it with the right IETF folks as early as possible, to avoid
wasting your time on an idea they will be blocked later.

HTTP hard-coding seems to be a small, albeit critical, part of
WebSocket so changing it to avoid conflicts with HTTP may be possible
without significant negative effects on the rest of the draft.

Good luck,

Alex.


 You already touch some aspects of HTTP such as authentication. Now throw
 things like NTLM or Digest authentication into the mix and you will
 quickly find that the current specification is a bit too limiting if the
 intention is that the upgrade requests should be processed by an HTTP
 server.
 
 Also regarding HTTP Upgrade semantics. If you want to follow that model
 then there is not really any relation between the initial Upgrade
 request and what takes place after the upgrade has completed. It's a
 complete switch of protocols, with their own semantics. 
 
 Regards
 Henrik



Re: Hello from Mozilla

2009-07-14 Thread Ian Hickson
On Tue, 14 Jul 2009, Alex Rousskov wrote:
 
 If you think your approach is the right one, I would suggest openly 
 discussing it with the right IETF folks as early as possible, to avoid 
 wasting your time on an idea they will be blocked later.

WebSocket is being discussed in the hybi IETF list.


 HTTP hard-coding seems to be a small, albeit critical, part of 
 WebSocket so changing it to avoid conflicts with HTTP may be possible 
 without significant negative effects on the rest of the draft.

The handshake is a pretty critical part of the security model of the 
WebSocket protocol. I don't really see how we can continue to have the 
safe handshake while allowing either the client or the server to send any 
arbitrary string.

WebSocket isn't an HTTP-upgraded protocol; it's just that its handshake 
happens to be such that it can trick HTTP servers into thinking that it 
is. In other words, HTTP Upgrade is not the initial handshake mechanism, 
it just looks like it is if you don't examine it closely.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-14 Thread Alex Rousskov
On 07/14/2009 06:01 PM, Ian Hickson wrote:
 On Tue, 14 Jul 2009, Alex Rousskov wrote:
 HTTP hard-coding seems to be a small, albeit critical, part of 
 WebSocket so changing it to avoid conflicts with HTTP may be possible 
 without significant negative effects on the rest of the draft.
 
 The handshake is a pretty critical part of the security model of the 
 WebSocket protocol. I don't really see how we can continue to have the 
 safe handshake while allowing either the client or the server to send any 
 arbitrary string.

Perhaps the WebSocket secure handshake should start _after_ the
successful upgrade? Is not that how HTTP Upgrade was intended to be used?

 WebSocket isn't an HTTP-upgraded protocol; it's just that its handshake 
 happens to be such that it can trick HTTP servers into thinking that it 
 is. In other words, HTTP Upgrade is not the initial handshake mechanism, 
 it just looks like it is if you don't examine it closely.

I think I understand the intent behind the trick, but if a message looks
like an HTTP message to the HTTP server or intermediary, the HTTP server
or intermediary may start doing HTTP-valid things to it, and those
things will not be valid from WebSocket point of view. Henrik provided a
few examples of that already.

I want to avoid the following Squid bug report 5 years from now:

Title: Squid breaks FooBar

Comment1: FooBar, a WebSocket application, works fine unless there is a
transparent Squid proxy in the way. I have attached a packet trace.

Comment2: Closed as invalid. Squid seems to be handling the HTTP
messages correctly. Squid is not responsible to what happens after
Upgrade, inside the tunnel.

Comment3: Reopened as critical. I need to make this work. Please do
something! I have read somewhere that if Squid would not add a Via or
XFF header and also that extra space character after a column,
everything would just work!

Comment4: Changed to enhancement: Rewrite Squid to support
WebSocket-compatible Upgrade exchange. Meanwhile, consider writing a
post-Squid eCAP module that will rewrite Squid-altered HTTP messages to
conform to WebSocket.


Cheers,

Alex.



Re: Hello from Mozilla

2009-07-14 Thread Ian Hickson
On Tue, 14 Jul 2009, Alex Rousskov wrote:
 On 07/14/2009 06:01 PM, Ian Hickson wrote:
  On Tue, 14 Jul 2009, Alex Rousskov wrote:
  HTTP hard-coding seems to be a small, albeit critical, part of 
  WebSocket so changing it to avoid conflicts with HTTP may be possible 
  without significant negative effects on the rest of the draft.
  
  The handshake is a pretty critical part of the security model of the 
  WebSocket protocol. I don't really see how we can continue to have the 
  safe handshake while allowing either the client or the server to send 
  any arbitrary string.
 
 Perhaps the WebSocket secure handshake should start _after_ the 
 successful upgrade? Is not that how HTTP Upgrade was intended to be 
 used?

If there are any bytes allowed from the client or the server before the 
handshake starts, then it is no longer secure. The idea is to make sure 
you can't smuggle though payloads from other protocols, since otherwise 
you could use WebSocket to connect to services that aren't expecting it.


  WebSocket isn't an HTTP-upgraded protocol; it's just that its 
  handshake happens to be such that it can trick HTTP servers into 
  thinking that it is. In other words, HTTP Upgrade is not the initial 
  handshake mechanism, it just looks like it is if you don't examine it 
  closely.
 
 I think I understand the intent behind the trick, but if a message looks 
 like an HTTP message to the HTTP server or intermediary, the HTTP server 
 or intermediary may start doing HTTP-valid things to it, and those 
 things will not be valid from WebSocket point of view.

Right -- and those things will prevent the connection, exactly as 
intended. The idea is to make sure that if there is anything in between 
that _isn't_ WebSocket-aware, the connection be dropped before the author
has any chance of sending data down the pipe. If we didn't do this, then 
it's possible that, e.g., Squid could be tricked into sending data from 
third-party servers in a way that the WebSocket client could not detect, 
thus breaching the same-origin security model.


 I want to avoid the following Squid bug report 5 years from now:
 
 Title: Squid breaks FooBar
 
 Comment1: FooBar, a WebSocket application, works fine unless there is a
 transparent Squid proxy in the way. I have attached a packet trace.
 
 Comment2: Closed as invalid. Squid seems to be handling the HTTP
 messages correctly. Squid is not responsible to what happens after
 Upgrade, inside the tunnel.
 
 Comment3: Reopened as critical. I need to make this work. Please do
 something! I have read somewhere that if Squid would not add a Via or
 XFF header and also that extra space character after a column,
 everything would just work!
 
 Comment4: Changed to enhancement: Rewrite Squid to support
 WebSocket-compatible Upgrade exchange. Meanwhile, consider writing a
 post-Squid eCAP module that will rewrite Squid-altered HTTP messages to
 conform to WebSocket.

If Squid changes the bytes that are sent from the client or by the server, 
then this bug will likely exist, yes. So don't do that. :-) If a man-in- 
the-middle proxy server modifies the bytes of connections it doesn't fully
understand, then WebSocket isn't the only thing that will break.

(Note that a min-in-the-middle proxy is not the same as a transparent 
proxy as defined by the HTTP spec. Per spec, a transparent proxy is a 
proxy that does not modify the request or response beyond what is required 
for proxy authentication and identification.)

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-14 Thread Henrik Nordstrom
ons 2009-07-15 klockan 00:51 + skrev Ian Hickson:

 Right -- and those things will prevent the connection, exactly as 
 intended. The idea is to make sure that if there is anything in between 
 that _isn't_ WebSocket-aware, the connection be dropped before the author
 has any chance of sending data down the pipe. If we didn't do this, then 
 it's possible that, e.g., Squid could be tricked into sending data from 
 third-party servers in a way that the WebSocket client could not detect, 
 thus breaching the same-origin security model.

Which is a clear sign that you MUST NOT use a message that even
resembles a HTTP message for the WebSocket handshake if you don't think
that the HTTP model can accomplish the protocol you need. As all
processing MUST bypass the HTTP stack of the server anyway the message
may in fact look any way you like as long as it can be identified..

But I honestly don't get what you are talking about here. How would
using HTTP Upgrade as intended possibly break the WebSocket security
model?

The WebSocket client has full control over the handshake, and is
responsible for sending it as a well formed HTTP message and also
parsing the HTTP response and should guarantee that it DOES NOT deliver
any non-websocket payload (i.e. 407 responses, 5xx responses etc) to the
WebSocket API user...

 If Squid changes the bytes that are sent from the client or by the server, 
 then this bug will likely exist, yes. So don't do that. :-) If a man-in- 
 the-middle proxy server modifies the bytes of connections it doesn't fully
 understand, then WebSocket isn't the only thing that will break.

Squid operates on HTTP messages.

While doing so HTTP REQUIRES it to modify the message in certain ways,
and allows it to modify it in several other ways.

- Addition of Via header (MUST)
- Various other informative headers added by Squid. (fully allowed)

But it's not my point. What I said is not even related to Squid but
general protocol design and your design goals with the websocket wire
protocol handshake resembling HTTP.

 (Note that a min-in-the-middle proxy is not the same as a transparent 
 proxy as defined by the HTTP spec. Per spec, a transparent proxy is a 
 proxy that does not modify the request or response beyond what is required 
 for proxy authentication and identification.)

Err, a semantically transparent proxy still modifies the request in many
ways. Via headers is the most obvious, but there is many many other
small things going on. It's just not allowed to change the request or
response in such way that the request/response means something else.

But yes, a transparently intercepting proxy is a different thing and
what Alex meant.

Regards
Henrik



Re: Hello from Mozilla

2009-07-14 Thread Alex Rousskov
On 07/14/2009 06:51 PM, Ian Hickson wrote:

 I want to avoid the following Squid bug report 5 years from now:

 Title: Squid breaks FooBar

 Comment1: FooBar, a WebSocket application, works fine unless there is a
 transparent Squid proxy in the way. I have attached a packet trace.

 Comment2: Closed as invalid. Squid seems to be handling the HTTP
 messages correctly. Squid is not responsible to what happens after
 Upgrade, inside the tunnel.

 Comment3: Reopened as critical. I need to make this work. Please do
 something! I have read somewhere that if Squid would not add a Via or
 XFF header and also that extra space character after a column,
 everything would just work!

 Comment4: Changed to enhancement: Rewrite Squid to support
 WebSocket-compatible Upgrade exchange. Meanwhile, consider writing a
 post-Squid eCAP module that will rewrite Squid-altered HTTP messages to
 conform to WebSocket.
 
 If Squid changes the bytes that are sent from the client or by the server, 
 then this bug will likely exist, yes. So don't do that. :-)

From HTTP point of view, some byte changes are not really changes and
some are actually required. Squid changes HTTP headers today and will
probably continue to do so 5 years from now, even when deployed as a
man in the middle.

 If a man-in- 
 the-middle proxy server modifies the bytes of connections it doesn't fully
 understand, then WebSocket isn't the only thing that will break.

WebSocket made the handshake bytes look like something Squid thinks it
understands. That is the whole point of the argument. You are sending an
HTTP-looking message that is not really an HTTP message. I think this is
a recipe for trouble, even though it might solve some problem in some
environments.

 (Note that a min-in-the-middle proxy is not the same as a transparent 
 proxy as defined by the HTTP spec. Per spec, a transparent proxy is a 
 proxy that does not modify the request or response beyond what is required 
 for proxy authentication and identification.)

That is why I quoted transparent. There is little transparent about
most transparent hijacking proxies. It is the reality that is not
covered by the HTTP specs but WebSocket will have to deal with it.
Moreover, I suspect similar arguments can be applied to surrogates and
even forward proxies that are covered by the specs and the specs allow
them to modify HTTP messages.

Cheers,

Alex.



Re: Hello from Mozilla

2009-07-14 Thread Ian Hickson
On Tue, 14 Jul 2009, Alex Rousskov wrote:
 
 WebSocket made the handshake bytes look like something Squid thinks it 
 understands. That is the whole point of the argument. You are sending an 
 HTTP-looking message that is not really an HTTP message. I think this is 
 a recipe for trouble, even though it might solve some problem in some 
 environments.

Could you elaborate on what bytes Squid thinks it should change in the 
WebSocket handshake?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-13 Thread Ian Hickson
On Tue, 7 Jul 2009, Alex Rousskov wrote:
 
 What is the motivation behind adding more ports?

WebSocket is its own protocol, so the right thing to do is to use new 
ports. However, WebSocket can be sent over 80 or 443 quite happily.


 Can websocket use port 80 (without CONNECT) and port 443 (with CONNECT)? 

Yes.


 I have noticed there is something about the Upgrade header in the 
 websocket draft so perhaps that mechanism can be polished to implement a 
 proper protocol switch? Or is that too late?

It actually does support a true HTTP Upgrade also, so that people who are 
already using ports 80 or 443 for HTTP can still use WebSocket if they are 
able to make their servers handle the protocol upgrade.

Cheers,
-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-13 Thread Henrik Nordstrom
ons 2009-07-08 klockan 15:16 +1200 skrev Amos Jeffries:

 CONNECT to port-80 by default is IMO not an option. It pretty much 
 defeats all the other HTTP-level security measures.

For what it's worth, RFC2817 Upgrading to TLS Within HTTP/1.1 requires
CONNECT to be accepted to port 80.

Not that I really know of anyone who uses this standards-track method
of TLS/SSL encrypting HTTP, just plain old HTTP over TLS/SSL (https).

Regards
Henrik



Re: Hello from Mozilla

2009-07-08 Thread Ian Hickson
On Tue, 7 Jul 2009, Alex Rousskov wrote:
 
 If WebSocket is a new protocol on top of TCP, new TCP ports are 
 appropriate.

Right.


 Like virtually any protocol on top of TCP, WebSocket can then rely on 
 HTTP CONNECT tunneling mechanism without trying to redefine or narrow it 
 down.

Right.


 If WebSocket is a new protocol on top of HTTP, then the talk of ports 
 seems far less appropriate because HTTP already has commonly used ports.

WebSocket is a protocol in its own right; however it happens to have a 
handshake that appears to HTTP servers as an HTTP Upgrade request so that 
it can share a port with HTTP servers.


 The fact that I could not tell which of the above statements is true 
 based on a quick draft read and things like prohibiting valid HTTP 
 messages in WebSocket responses worry me, but it is likely I just missed 
 some important pieces or caveats.

I've tried adding a section to the intro to make this clearer. Please let 
me know if it can be improved further.


  I have noticed there is something about the Upgrade header in the 
  websocket draft so perhaps that mechanism can be polished to 
  implement a proper protocol switch? Or is that too late?
  
  It actually does support a true HTTP Upgrade also, so that people who 
  are already using ports 80 or 443 for HTTP can still use WebSocket if 
  they are able to make their servers handle the protocol upgrade.
 
 As far as I can tell, the protocol does not support true HTTP Upgrade 
 sequence but just one specific exchange of hard-coded (down to each 
 octet level!) HTTP messages. This clever hack smells like a layering 
 violation and can be a real pain to support if the client or server HTTP 
 stack just happens to generate slightly different messages.

Well, the client is a WebSocket client, so it can always generate the 
exact byte sequence specified in the spec almost by definition. The server 
side is restrictive, but should be implementable without too much trouble 
so long as there is a way to register a protocol handler that can prevent 
the HTTP side of the server from sending any bytes at all as part of the 
response. I agree that this is suboptimal, but we're somewhat forced into 
this by one of our security design requirements (that the handshake be 
very specific to avoid enabling request smuggling or other such behaviour 
-- basically we really want to be sure we're talking to a WebSocket server 
at the end of the handshake).

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: Hello from Mozilla

2009-07-07 Thread Alex Rousskov
On 07/02/2009 06:59 PM, Jason Duell wrote:

 Hi there!   I'm doing some work for Mozilla on the network stack for
 Firefox, and there are a couple of items I wanted to run by the Squid
 development team.

Hello Jason,

I am forwarding your email to squid-dev mailing list where it will
receive more attention.

 1) I have a quick question about the limitations that you put by default
 on the CONNECT method.  squid.conf contains
 
 # Deny CONNECT to other than SSL ports
 http_access deny CONNECT !SSL_ports
 
 So squid by default only allows CONNECT to port 443.   I assume this is
 a rule-of-thumb security measure, since you figured that port 443 is the
 only common legitimate case for CONNECT?   How long has this been the
 default behavior?  Do you know if other proxy servers out there also do
 this?

You have identified the main reason correctly. This default has been
added many years ago but I do not know when. I would expect some other
popular proxies to restrict tunneling as well, but I have not tested it.

 The reason I ask is because we're looking to take a patch that
 implements the IETF websockets protocol:
 
 http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-17
 
 I noticed that in section 3.1.3 the spec relies implicitly on CONNECT
 being allowed to arbitrary ports.  But this is not the case for default
 installs of squid, and thus I fear that the general approach may be flawed.
 
 I suppose we could ask that you allow arbitrary CONNECT access (or at
 least to the well-known websockets ports: 80/81/815).  But I'm
 guessing that wouldn't help much, as it would probably take many years
 for that change to roll out across the net.

I would also expect many firewalls to block port 81 and 815 by default
so even if Squid allows those ports, websocket clients that do not hide
behind Squid will still have problems (unless websocket is restricted to
proxies).

 Any thoughts you have on the matter would be much appreciated.   In
 general, it seems that handling proxies correctly is turning out to be
 one of the trickier parts of implementing a websockets-like API, so we
 may want to pick your brains some more in the future with other ideas.

What is the motivation behind adding more ports? Can websocket use port
80 (without CONNECT) and port 443 (with CONNECT)? I have noticed there
is something about the Upgrade header in the websocket draft so perhaps
that mechanism can be polished to implement a proper protocol switch? Or
is that too late?


 2) A totally unrelated issue:  I assume by now you're aware that Firefox
 (and all other major browsers besides Opera) now no longer renders
 replies from squid or other proxies for failed HTTPS requests.   For
 details see
 
 https://bugzilla.mozilla.org/show_bug.cgi?id=479880
 
 I meant to email you about this before the patch went in, but then I got
 busy :)   I'm not sure that there's much to talk about now that the fix
 is in (it's gross, and we theoretically ought to be able to do better,
 but it would be a lot of work, so I don't think it's going to happen).  
 But I wanted you to know.  It's really just a UI issue (you can tell I'm
 a systems programmer...)

Yeah, looks like a browser security bug has been replaced with usability
and compliance bugs. There is nothing Squid can do about it but thank
you for letting is know as this info may be useful when troubleshooting.

 P.S. So every time that I set up squid on my machine to test something,
 it always denies access to me out of the box.  I finally figured out
 it's because you don't allow localhost connections by default.  Should
 you be adding a line like
 
acl localnet src localhost
 
 to squid.conf?  Is there a reason why you're allowing 10.0.0.1, etc. to
 connect, but not localhost?

Good question. I will let others answer it :-).

Thank you,

Alex.



Re: Hello from Mozilla

2009-07-07 Thread Robert Collins
On Tue, 2009-07-07 at 17:01 -0600, Alex Rousskov wrote:
  The reason I ask is because we're looking to take a patch that
  implements the IETF websockets protocol:
  
  http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-17
  
  I noticed that in section 3.1.3 the spec relies implicitly on CONNECT
  being allowed to arbitrary ports.  But this is not the case for default
  installs of squid, and thus I fear that the general approach may be flawed.

I think it has several serious challenges; I doubt it could be deployed
in (say) Australia *at all*.

  I suppose we could ask that you allow arbitrary CONNECT access (or at
  least to the well-known websockets ports: 80/81/815).  But I'm
  guessing that wouldn't help much, as it would probably take many years
  for that change to roll out across the net.
 
 I would also expect many firewalls to block port 81 and 815 by default
 so even if Squid allows those ports, websocket clients that do not hide
 behind Squid will still have problems (unless websocket is restricted to
 proxies).

So squid has two primary uses:
 - caching
 - security

From a caching perspective, websockets are just overhead - uncacheable
content simply adds overhead to what squid has to do. Just using TCP/IP
would be a lot better and faster. 

Many ISP's use interception techniques to deploy squid and other caches.
These operate by performing a MITM attack on TCP/IP traffic. Policy
limits in these deployments are often turned off (because users using
TCP/IP would expect to access any url), while at the same time lifetime
heuristics tend to be turned way up (to maximise the hit rate the ISP
can achieve). As such, I'd expect this spec to have requests fail all
over the place. There are mechanisms for such requests to be reissued on
fresh, direct TCP connections by the router that performed the
interception - but the specific toolchain deployed will vary how
successful that is. Note that this has nothing to do with the use of
Connect: - squid, or other proxies, would see the 'Upgrade:' request.

From a security perspective, there are two sub issues:
 - preventing malicous use (e.g. spam bouncing)
 - policy restrictions (acls, corporate policy, content filtering...)

Malicious use covers things like not being an open proxy, and not
permitting connections to SMTP servers for any clients. This is where
the default Connect limit comes in - and also the prevention of http
requests to port 25.

  Any thoughts you have on the matter would be much appreciated.   In
  general, it seems that handling proxies correctly is turning out to be
  one of the trickier parts of implementing a websockets-like API, so we
  may want to pick your brains some more in the future with other ideas.
 
 What is the motivation behind adding more ports? Can websocket use port
 80 (without CONNECT) and port 443 (with CONNECT)? I have noticed there
 is something about the Upgrade header in the websocket draft so perhaps
 that mechanism can be polished to implement a proper protocol switch? Or
 is that too late?

I'd like to understand the motivation behind not just using TCP/IP with
a SOCKS proxy. The whole websockets thing seems like baroque cruft, TBH.
A lot of complexity, more layers that things can go wrong in (and that
security holes can be found in).

  2) A totally unrelated issue:  I assume by now you're aware that Firefox
  (and all other major browsers besides Opera) now no longer renders
  replies from squid or other proxies for failed HTTPS requests.   For
  details see
  
  https://bugzilla.mozilla.org/show_bug.cgi?id=479880
  
  I meant to email you about this before the patch went in, but then I got
  busy :)   I'm not sure that there's much to talk about now that the fix
  is in (it's gross, and we theoretically ought to be able to do better,
  but it would be a lot of work, so I don't think it's going to happen).  
  But I wanted you to know.  It's really just a UI issue (you can tell I'm
  a systems programmer...)

Thanks. It would be nice if mozilla would create a context *for the
proxy* and use that to show the non 200 response. Debuggability is
kindof important :).

  P.S. So every time that I set up squid on my machine to test something,
  it always denies access to me out of the box.  I finally figured out
  it's because you don't allow localhost connections by default.  Should
  you be adding a line like
  
 acl localnet src localhost
  
  to squid.conf?  Is there a reason why you're allowing 10.0.0.1, etc. to
  connect, but not localhost?

I'd be open to us changing this. It is a [small] risk for a bastion host
to allow connections from itself because a different account being
compromised then allows access via the proxy. I have no evidence to make
an assertion about the frequency of deployments on a bastion host vs
behind one, and so the only argument I have for preserving it is 'secure
as possible by default', which while a good argument isn't the end of
the discussion.

-Rob



Re: Hello from Mozilla

2009-07-07 Thread Tres Seaver
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Robert Collins wrote:

 P.S. So every time that I set up squid on my machine to test something,
 it always denies access to me out of the box.  I finally figured out
 it's because you don't allow localhost connections by default.  Should
 you be adding a line like

acl localnet src localhost

 to squid.conf?  Is there a reason why you're allowing 10.0.0.1, etc. to
 connect, but not localhost?
 
 I'd be open to us changing this. It is a [small] risk for a bastion host
 to allow connections from itself because a different account being
 compromised then allows access via the proxy. I have no evidence to make
 an assertion about the frequency of deployments on a bastion host vs
 behind one, and so the only argument I have for preserving it is 'secure
 as possible by default', which while a good argument isn't the end of
 the discussion.

Your argument is subject to reductio ad absurdam:  if you want secure
as possible by default, then the default config shold not allow proxied
access from *any host at all*.  Any host other than localhost should be
*less* trusted than localhost.

I would argue that enabling only localhost for the default forward
proxy configuration is a sane default:  people configuring things like
bastions ought not to expect to use out-of-the box configs without
review / tweakage, while people using Squid as a personal cache ought
not to have to do such tweaks.


Tres.
- --
===
Tres Seaver  +1 540-429-0999  tsea...@palladion.com
Palladion Software   Excellence by Designhttp://palladion.com
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFKVARQ+gerLs4ltQ4RAhlJAKDWsjrr/7IT45r4IPXsXt5Xyfa0zwCffrfr
hLbI2vMOIWeHA09Mf+Kdg2k=
=bVwt
-END PGP SIGNATURE-



Re: Hello from Mozilla

2009-07-07 Thread Amos Jeffries

Robert Collins wrote:

On Tue, 2009-07-07 at 17:01 -0600, Alex Rousskov wrote:

The reason I ask is because we're looking to take a patch that
implements the IETF websockets protocol:

http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-17

I noticed that in section 3.1.3 the spec relies implicitly on CONNECT
being allowed to arbitrary ports.  But this is not the case for default
installs of squid, and thus I fear that the general approach may be flawed.


I think it has several serious challenges; I doubt it could be deployed
in (say) Australia *at all*.


I suppose we could ask that you allow arbitrary CONNECT access (or at
least to the well-known websockets ports: 80/81/815).  But I'm
guessing that wouldn't help much, as it would probably take many years
for that change to roll out across the net.

I would also expect many firewalls to block port 81 and 815 by default
so even if Squid allows those ports, websocket clients that do not hide
behind Squid will still have problems (unless websocket is restricted to
proxies).


I'm open to adding 815, maybe 81.  Though as Robert says, the utility 
may not be as much as the authors think.


CONNECT to port-80 by default is IMO not an option. It pretty much 
defeats all the other HTTP-level security measures. Port-81 is 
borderline on the risky side. Considering the number of proxies and 
web-apps which historically use it for regular internal LAN HTTP stuff. 
 Admin who know they need CONNECT to those ports are free to do so of 
course.


IIRC, there is also another HTTPS port 5-something, and some other 
protocols needing consideration in the same commit.




So squid has two primary uses:
 - caching
 - security

From a caching perspective, websockets are just overhead - uncacheable
content simply adds overhead to what squid has to do. Just using TCP/IP
would be a lot better and faster. 


Many ISP's use interception techniques to deploy squid and other caches.
These operate by performing a MITM attack on TCP/IP traffic. Policy
limits in these deployments are often turned off (because users using
TCP/IP would expect to access any url), while at the same time lifetime
heuristics tend to be turned way up (to maximise the hit rate the ISP
can achieve). As such, I'd expect this spec to have requests fail all
over the place. There are mechanisms for such requests to be reissued on
fresh, direct TCP connections by the router that performed the
interception - but the specific toolchain deployed will vary how
successful that is. Note that this has nothing to do with the use of
Connect: - squid, or other proxies, would see the 'Upgrade:' request.

From a security perspective, there are two sub issues:
 - preventing malicous use (e.g. spam bouncing)
 - policy restrictions (acls, corporate policy, content filtering...)

Malicious use covers things like not being an open proxy, and not
permitting connections to SMTP servers for any clients. This is where
the default Connect limit comes in - and also the prevention of http
requests to port 25.


Any thoughts you have on the matter would be much appreciated.   In
general, it seems that handling proxies correctly is turning out to be
one of the trickier parts of implementing a websockets-like API, so we
may want to pick your brains some more in the future with other ideas.

What is the motivation behind adding more ports? Can websocket use port
80 (without CONNECT) and port 443 (with CONNECT)? I have noticed there
is something about the Upgrade header in the websocket draft so perhaps
that mechanism can be polished to implement a proper protocol switch? Or
is that too late?


I'd like to understand the motivation behind not just using TCP/IP with
a SOCKS proxy. The whole websockets thing seems like baroque cruft, TBH.
A lot of complexity, more layers that things can go wrong in (and that
security holes can be found in).


2) A totally unrelated issue:  I assume by now you're aware that Firefox
(and all other major browsers besides Opera) now no longer renders
replies from squid or other proxies for failed HTTPS requests.   For
details see

https://bugzilla.mozilla.org/show_bug.cgi?id=479880

I meant to email you about this before the patch went in, but then I got
busy :)   I'm not sure that there's much to talk about now that the fix
is in (it's gross, and we theoretically ought to be able to do better,
but it would be a lot of work, so I don't think it's going to happen).  
But I wanted you to know.  It's really just a UI issue (you can tell I'm

a systems programmer...)


Thanks. It would be nice if mozilla would create a context *for the
proxy* and use that to show the non 200 response. Debuggability is
kindof important :).


These are the reponse codes I'm aware of people trying to use with Squid 
CONNECT. For now the admins are hacking around the browsers that don't 
support custom errors.


Taking 404 access denied as assumed.

 * the authenticated proxy (407) response needing a login popup.

 * the 

Re: Hello from Mozilla

2009-07-07 Thread Alex Rousskov
On 07/07/2009 05:39 PM, Ian Hickson wrote:
 On Tue, 7 Jul 2009, Alex Rousskov wrote:
 What is the motivation behind adding more ports?
 
 WebSocket is its own protocol, so the right thing to do is to use new 
 ports. However, WebSocket can be sent over 80 or 443 quite happily.

If WebSocket is a new protocol on top of TCP, new TCP ports are
appropriate. Like virtually any protocol on top of TCP, WebSocket can
then rely on HTTP CONNECT tunneling mechanism without trying to redefine
or narrow it down.

If WebSocket is a new protocol on top of HTTP, then the talk of ports
seems far less appropriate because HTTP already has commonly used ports.

The fact that I could not tell which of the above statements is true
based on a quick draft read and things like prohibiting valid HTTP
messages in WebSocket responses worry me, but it is likely I just missed
some important pieces or caveats.


 I have noticed there is something about the Upgrade header in the 
 websocket draft so perhaps that mechanism can be polished to implement a 
 proper protocol switch? Or is that too late?
 
 It actually does support a true HTTP Upgrade also, so that people who are 
 already using ports 80 or 443 for HTTP can still use WebSocket if they are 
 able to make their servers handle the protocol upgrade.

As far as I can tell, the protocol does not support true HTTP Upgrade
sequence but just one specific exchange of hard-coded (down to each
octet level!) HTTP messages. This clever hack smells like a layering
violation and can be a real pain to support if the client or server HTTP
stack just happens to generate slightly different messages. Again,
perhaps general-purpose client and server stacks are simply not the
targeted audience for the protocol and their limitation simply do not
matter.

Cheers,

Alex.



Re: Hello from Mozilla

2009-07-07 Thread Robert Collins
On Tue, 2009-07-07 at 22:28 -0400, Tres Seaver wrote:

 I would argue that enabling only localhost for the default forward
 proxy configuration is a sane default:  people configuring things like
 bastions ought not to expect to use out-of-the box configs without
 review / tweakage, while people using Squid as a personal cache ought
 not to have to do such tweaks.

Sure; as I said, a) we don't have really good data here, and b) I'm open
to it being changed :)

-Rob


signature.asc
Description: This is a digitally signed message part


Re: Hello from Mozilla

2009-07-07 Thread Amos Jeffries

Robert Collins wrote:

On Tue, 2009-07-07 at 22:28 -0400, Tres Seaver wrote:


I would argue that enabling only localhost for the default forward
proxy configuration is a sane default:  people configuring things like
bastions ought not to expect to use out-of-the box configs without
review / tweakage, while people using Squid as a personal cache ought
not to have to do such tweaks.


Sure; as I said, a) we don't have really good data here, and b) I'm open
to it being changed :)


There changed already in HEAD.
Will be effective from 3.1.0.10 and 3.0.STABLE17

Amos