What are the security issues around an open websocket connection? - html

I am building an application that is using websockets. I am only going to allow authenticated users to open a websocket connection with the server after they have logged in and have been granted a session id.
Once I have opened a websocket connection with an authenticated user, the current "page" then holds the details of the open websocket connection. At this point, is this connection relatively safe? Or should I really be checking some token on every message within my own application level protocol that comes in over the websocket?
Are there any known cross-site forgery type security issues? Where someone could coop an open websocket by getting the authenticated user to execute some javascript in some manner - resulting in the ability to exploit the open websocket connection?

1) The connection is safe, when you make it safe on the server side. So you have to send a session ID via WebSockets, verify on the server side that it is correct and mark the connection as valid. Authentication is more difficult with HTTP, because HTTP is stateless ( unlike raw TCP ). Of course it is still possible to hijack TCP connection, but it's not that easy ( see for example this article ) and if it happens, then nothing ( except for TLS ) can help you.
2) Well, if you wrap your WebSocket connection with an anonymous function like that:
(function() {
var ws = new WebSocket("ws://localhost:1000");
// some other stuff
})();
then no external JavaScript will be able to access it, so you don't have to worry about that.

Related

Why do we need to mention the ws protocol in WebSocket constructor?

I have just started learning about WebSocket recently. As from http://www.websocket.org/ it is mentioned that A WebSocket connection is established by upgrading from the HTTP protocol to the WebSockets protocol during the initial handshake between the client and the server. Again, To connect to an end-point, just create a new WebSocket instance, providing the new object with a URL that represents the end-point to which you wish to connect, as shown in the following example. Note that a ws:// and wss:// prefix are proposed to indicate a WebSocket and a secure WebSocket connection, respectively.
var myWebSocket = new WebSocket("ws://www.websockets.org");
My question is why do I need to include ws or wss in the url when the HTTP server knows that it should upgrade the protocol ? I have gone through few tutorials. In all of those the url argument to the WebSocket constructor is the same as the HTTP server url. Is it because, We first establish connection to that url and then the WebSocket is bound to that connection ? I am a newbie on this. Some clear explanation will be highly appreciated regarding this.
Just like you need to specify http:// or https:// to tell the browser whether to use SSL with HTTP, you need ws:// or wss:// to let it know whether to use SSL with WebSockets.

When do we say a connection is established in a Web Application?

Assume I have a simple ASP.NET MVC application with an Index view that just shows some static data.
Considering the fact that the web is stateless, when a browser requests for this index.cshtml, a HTTP Get request is made and the server sends the contents of the page to the client.
In Such case is there an entity called connection? If so when can we say that connection is established?
Hope my question is clear.
A connection is established between the client (browser) and the underlying web server (IIS) prior to any invocation of your MVC application.
If you get a request in your web application, then a TCP connection has already been established and an HTTP request has been sent to the server over TCP. With keep-alive semantics, multiple requests may use the same connection, and of course multiple actions could even be called for the same request.
So basically, the establishment of a connection is not something that is particularly useful for a web application to indicate or track, if that is what you are trying to do.
The connection is estabished to the IIS Server/Process and then forwarded to .NET, so the moment IIS receives it, it's 'established'
The HTTP protocol is based on the TCP protocol. Before the GET request is made, a TCP connection must be made.
"The connection is closed" happens when the TCP connection is closed, usually after a single request/response interaction.
The connection may be kept open by using Keep-Alive.

html5 WebSocket

I already have a server with port and want to write a web app to get the information form the port. Will this be possible with WebPorts?
The Client doesn't even need to talk back to the server, which is the whole point of websockets I would imagine, but since I already have the ports setup, I might be easier and cleaner to just connect and get the info without having to refresh.
WebSockets are not intended as clear TCP channels over which other existing protocols can be implemented.
WebSockets are designed to allow messages to be sent between a client and server, where an event is raised each time a message is received.
Hence a WebSocket client cannot simply connect to an existing TCP server - that server also has to speak the WebSocket protocol.
You could of course write a WebSocket-based server that does nothing but act as a proxy to existing network services.
I think you want websockify which is a WebSocket to plain TCP socket bridge/proxy. It also allows sending and receiving of binary data with the older version of the WebSocket protocol which hadn't yet added direct binary data support.
Disclaimer: I created websockify.

Cross Domain sessions and web sockets

I am working on a site that will be using HTML5 sockets to communicate with other server. At that time our users will be logged in , I can't code on other server . I am using PHP at server side. I don't know whether other server has even PHP or not. Client says PKI is a solution. So if user login on our server then I start their communication with HTML5 sockets towards other server to send and receive data. So how can other server authenticate them? I also think that I can have a userkey (like 32hash format) that is sent with HTML5 socket while communication that other server validate and then start working with that user. So client says that hacker can see data over network so I think SSL can work for it. What you guys suggest in such scenario? Please advise
More details:
There will be connection made between our users and another server using apache thrift(will be using TCP), and scenario is that user will login to our site, then we will connect them via HTML5socket to apache thrift on different domain, so in HTML5socket communication we will be forwarding userid to tell thrift server that which user is this, so it is fine. But there are two problems,
As HTML5sockets are at client side then a hacker can create his/her own socket and connect to that server in same way and use some one's id as these are just simple integers.
If we will append some thing in data then a hacker sitting on the network can get it like some hackers do this for session hijacking.
So that's why I am not sure that whether using a sort of SSL or TLS will solve the problem or some PKI or some other digital certificate. So that's why I am asking that here.
thanks
SSL cannot solve this problem. SSL is about creating a secure link between the client and server, it does absolutely nothing to protect the server from a malicious client. SSL cannot solve the problem of SQL Injection or in your case Insecure Direct Object Reference relating to the user id. Judging by this SSL suggestion you probably have never heard of TamperData, which allows you to read/intercept and modify all HTTPS traffic generated by your browser (Including components like flash and JavaScript), BURP is more advanced but does the same thing.
The right way to do this is to have a shared session store that your collection of servers can access. The client is issued a very large random number or cryptographic nonce that it uses as a verification token, which is kind of like a session id. This verification token is used to look up session state in the data store. The communal session store could be as simple as a PHP page that accepts the verification token as a parameter and tells you if its linked to a valid session.
Having 3rd parties issue a callback to verify the session is really the "right way" to do this. It is possible to do this with cryptography, although it is a misuse of cryptography because it introduces the possibility of an attack, where as a callback is absolute. The PHP server can issue the JavaScript client an HMAC token consisting of the user id, a timestamp and the message authentication code. The tricky part is that both the PHP server and any 3rd party will have to share a secret in order to verify the message authentication code. If done properly you can transmit the client can transmit the token, and 3rd parties can verify that the session hasn't expired based on the timestamp and that your servers issued the token (instead of a hacker's forgery) based on the message authentication code.

Websocket authentication

I'm running a websocket server and asking myself, if it's planed, that clients authentication will be done with handshake in future... draft xxxx maybe :)
Do you have information? I have heard that with draft07 a session id can be sent to server, so maybe that can help to auth the client...
What I'm doing atm is to wait a maximum of 10 seconds, till the clients sends me a message with login header, username and password. But i think this is not "THE" solution. How do you guys out there doing it?
The WebSockets protocol permits standard HTTP authentication headers to be exchanged during the handshake. If you have a WebSockets server that plugs into an existing web server as a module then existing authentication in the web server should already work. Otherwise if you have a standalone WebSockets server then you may need to add the authentication support.
Update
As #Jon points out, unlike normal HTTP/XHR requests, the browser API does not allow you to set arbitrary "X-*" headers for WebSocket connections. The only header value that you can set is the protocol. This is unfortunate. One common solution is to use a ticket based system that relies on existing HTTP mechanism for authorization/authentication and then this ticket is passed along with the websocket connection and validated that way: https://devcenter.heroku.com/articles/websocket-security