[whatwg] TCPConnection feedback

(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