- From: Philipp Serafin <phil127@gmail.com>
- Date: Tue, 24 Jun 2008 16:29:26 +0200
(Sorry if this counts as thread necromancy. The discussion just didn't seem to have come to an end yet.) On Fri, Jun 20, 2008 at 3:55 PM, Frode B?rli <frode at seria.no> wrote: > I would manage, but i do not like the implementation (it is much more > complex than it needs to be). I would basically hate doing extra work > because the implementation wasnt good enough. > > It is worth spending months improving the implementation here, if it > saves only one minute of work for each of the millions of web > developers out there, in the future. Alright, point taken. You're of course absolutely right with that :) I agree, it would be very convenient to basically set up and control a web app in a single connection. However, I think there are valid use cases for just the opposite set up as well. So, if we use a HTTP handshake, we should provide two ways. > If it is impossible to use HTML, then it is absolutely required that > Session ID is added as a standard header - since that will be the only > way of linking the generated HTML with the separate persistent > connection. You can't assume that an application server or the web > server will be able to parse the cookie, since the cookie format is > different for each programming language/application. This depends on the layer where the session management takes place. For example, PHP's existing session handling system already uses cookies. So, a hypothetical future "PPHP" version of PHP could extend the session system to support this. This feature couldn't be implemented in the afromentioned "few lines of perl" though. If this feature is still wanted in a standardized way, I think the idea to have the server advertise that it wants to change the protocol but to let the client do the actual switch would be the best way. >The HTTP 101 Switching Protocols can be sent by the server, without >the client asking for a protocol change. The only requirement is that >the server sends 426 Upgrade Required first, then specifies which >protocol to switch to. The protocol switched to could possibly be the >one proposed in the beginning of this thread. I don't see how we could use 426 as a notification that the client should open a WebSocket connection. 426 is still an error code, so if you send it as the reply to the initial GET request, you can't be sure the HTML file you pushed gets interpreted the correct way. While this would probably work, it would be semantically unclean at best. However, the TLS -over-HTTP spec states "As specified in HTTP/1.1, the server MAY include an Upgrade header in any response other than 101 or 426 to indicate a willingness to switch to any (combination) of the protocols listed." <http://www.ietf.org/rfc/rfc2817.txt> I can't seem to find any mention about this in the HTTP spec though. Is this implemented or at least widely known? Maybe you could reasoneably assume that a proxy keeps a connection open if an upgrade seems imminent? If this works, we could extend Michael's original algorithm as follows (this would be in addition to the "new WebSocket()" interface and would not replace it) PROPOSAL: Turning an existing HTTP connection into a WebSocket connection: If the server sends a Connection: Upgrade header and an Upgrade header with a "WebSocket" token as part of a normal response and if the resource fetched established a browsing contest, the client must not issue any other requests on that connection and must initiate a protocol switch. After the switch has finished, the client would expose the connection to the application via a DefaultWebSocket property or something similar. An exchange could look like this: C: GET /uri HTTP/1.1 C: Host: example.com C: [ ... usual headers ... ] C: S: HTTP/1.1 200 OK S: Content-Type: text/html S: [ ... usual headers ... ] S: Upgrade: WebSocket/1.0 S: Connection: Upgrade S: S: [ ... body ... ] C: OPTIONS /uri HTTP/1.1 C: Host: example.com C: Upgrade: WebSocket/1.0 C: Connection: Upgrade C: S: HTTP/1.1 101 Switching Protocols S: Upgrade: WebSocket/1.0 S: Connection: Upgrade S: C/S: [ ... application specific data ... ] Because the connection would be same-origin pretty much per definition, no access checks would be needed in that situation. Would something like this be doable and wanted? > >> On Fri, Jun 20, 2008 at 1:52 PM, Frode B?rli <frode at seria.no> wrote: >>> I have a proposal for a cross domain security framework that i think >>> should be implemented in browsers, java applets, flash applets and >>> more. >> If we use any kind of verification that happens outside the >> connections, we should at least a hint inside the connection, which >> host the browser wants to connect though. I think raw TCP connections >> would cause major security holes with shared hosts, even if >> cross-domain connections need a DNS record. > > Yes, if we are using the WebSocket - but not if using the TCP > connection. Nobody will be allowed to run a separate application that > listens on a port on a shared server anyway. > >> Consider the following scenario: >> >> Bob and Eve have bought space on a run-of-the-mill XAMPP web hoster. >> They have different domains but happen to be on the same IP. Now Eve >> wants do bruteforce Bob's password-protected web application. So she >> adds a script to her relatively popular site that does the following: > > So Bob will DDOS his own server? And my proposals allows using > hostnames OR ip-addresses in the DNS TXT record, so unless Eve add her > own IP-address to the DNS then Bob can't create scripts that are > allowed to access her hostname. I'm sorry, if my wording was unclear. I was talking about a typical shared hosting setup where customers get FTP access to a directory where they can upload pages and scripts but for example no shell access. Bob and Eve would have different directories on the same server. Requests to their sites would go to the same port on the same IP. The server would use the Host header to determine which request goes to which site. In the scenario, Eve would try to attack Bob's application. > > Why could he not just do a local connect to the port? Besides; if you > have login access to the same server as your target - there are a lot > much more efficient ways to find access information. Eve could connect directly. However, then her IP would be in Bob's logs and she could be shut down quickly. If she makes the detour over a client-side scripts, only IPs of random visitors of Eve's website would be logged. > >> 1) Open a TCP connection to her own domain on port 80. As far as the >> browser is concerned, both origin and IP adress match the site one's, >> so no cross domain checks are performed. > > The server will not be able to match a connection to an IP adress with > the correct script on the same server. My proposal of reusing the same > connection as the page was served from does not have this problem - as > the web server can match the connection with the exact > hostname/script. I agree here. > >> 2) Forge HTTP requests on that connection with Bob's site in the Host >> header and bruteforce the password. The Browser can't do anything >> about this, because it treats the TCP connection as opaque. The >> firewall just sees a legitimate HTTP request on a legitimate port. > > Still, that is more easily done if you are sitting on the local server > using the server side script. Also the connections will be many times > faster locally than all connections from outside users combined. See above. > >> If Bob checks his logs, he will see requests from IPs all oer the >> world. Because Eve has control about the Referrer and >> Access-Control-Origin headers, there is no trace that leads back to >> her. She might even have send the headers with forged values to shift >> suspicion to another site. > > No trace leads back to Bob if he sits locally either (it would > probably be more confusing). > > Perhaps the protocol should send another header stating the origin of > the script that started the request? For HTTP-based connections, this is exactly what Access-Control-Origin is doing. For pure TCP connections, this would not be possible, because, after all, they wouldn't be pure anymore :) > >> Note that the web hoster doesn't need to support WebSocket server side >> in any way for this to work. > > The web hoster will not allow a shared hosting customer to create > programs that listen on arbitrary ports on the server, so for > TCPConnection this is not an issue. > The web hoster may not, but the interface on the browsers would still work. > > A big problem here is that we are discussing two separate things in > the same threads. TCPConnection is one suggestion, WebConnection is > another. I agree. This attack would only work on pure TCP connections, not on HTTP-based connections. If I see it correctly, we have the following proposals currently: - Client-initiated HTTP 101, access checks via Access Control (The original proposal) - "Server-initiated" HTTP 101 on an exisiting connection, no checks necessary - Client-initiated HTTP 101, access checks via DNS/XSocket - Pure TCP, access checks via DNS/XSocket Is this correct? I think we should decide if we should continue the discussion about a HTTP-based or a pure TCP connection or if we should include both. > > My DNS record security framework will work for both implementations. For pure TCP connections, I don't see how it would alleviate the attack above. I think the XSocket proposal would solve the problem though. For HTTP-based connections, it would work, but I think Access Control would solve the same problems and would be much easier to implement and control. > > Security issues regarding TCPConnection should be discussed. Java > applets can already do pure TCP connections to the server they are > hosted on, and I have never heard of the type of attack that you > describe above. > > Regards, Frode > Regards, Philipp Serafin
Received on Tuesday, 24 June 2008 07:29:26 UTC