I am trying to open a websocket to a server with kerberos authentication, error during handshake occurs (error code : 400) ;
i saw it's not possible to send credentials through web socket and what i have to do is to set the username and password through web socket cookie and the server will read them.
So how can i set cookies for web socket ?
thank you,
It depends on the browser. You may implement handling cookies if they arrive with the initial HTTP request to initiate a WebSocket connection, but if you can't require your users to, say, use Safari, which sends cookies with WebSocket open requests, and not Chrome, which does not, you'll probably have to implement a mechanism for the client to send in the session identifier in-band.
One simple way to achieve this is for the client code to send in the session identifier as the first message in response to the open event, and the server code to interpret the first incoming message's content as the session cookie, to set up the appropriate privilege context (or perhaps close the connection if the cookie is unknown or otherwise grants no privileges to its bearer).
Alternatively, if your WebSocket protocol has some sort of structured message infrastructure, you may define a specific message type for passing a session cookie to the server, as well as a matching response type for the server to let the client know what it thinks of the cookie.
It may be tempting to pass the session cookie in an URI parameter, as in ws://example.com/service?SESSION=123456. This can be adequate in prototyping, but it is probably ill-advised in production, since session cookies should generally be treated as more sensitive than it is customary to treat the list of URIs requested from a web server. Passing session cookies in such a way can work in the short term, but may increase the risk of their accidental exposure via, say, careless analytics techniques. This concern could in some other context be alleviated by passing the sensitive identifier in the body of the request (for example, as a so-called POST parameter), but WebSocket open requests can not have a non-empty body.
You can set cookies for a webSocket connection the same way you set regular cookies, with document.cookie = xxxx. All webSocket connections start with an HTTP request (with an upgrade header on it) and the cookies for the domain you are connecting to will be sent with that initial HTTP request to open the webSocket.
So, as long as you are doing the webSocket connection to the same domain as your web page, then you can just set a cookie for that web page and it will be sent with the webSocket connection request. And, as with other cookies, you set a cookie using document.cookie as described here on MDN.
Related
I have a WebSocket server written in javascript and send data to it from my CSharp application. Now how can I make sure that these are correct? I thought I could do something with hash values but I don't know how to do that. Does anyone have an idea or code example?
The first thing to understand is the types of WebSocket protocol/transports. WebSocket ws:// transport is basically unusable in terms of security as it uses HTTP. The wss:// protocol establishes a secure connection over TCP/HTTPS. The wss protocol, therefore, protects against man-in-the-middle attacks.
There is multiple methods to authenticate a user when setting up a WebSocket connection, and none are perfect. Since the standard WebSocket usage prevents additional headers from being set such as custom authentication headers, tried and true methods that would be used in a standard HTTPS request to verify the validity of a client can't be used.
The link here outlines some common methods to keep the client and server in sync while setting up a WebSocket connection, and still add some security so the server can keep track of what clients are opening WebSocket connections. There are a lot of workarounds listed for the server to safely receive sensitive, authentication data from the client.
I am developing a web app and I am on a process of handling the Authentication of user. I am able to get the access token by initially making HTTP POST call to the API.
The idea know is where to store it so that it is not vulnerable to XSS.
Have heard of HttpOnly Cookie which makes it possible that the cookie is readable by the client (javascript), but the thing is why would I need something to store on my end when I cannot access it. How do I sent back to the backend (API) access token stored into coockie with http only since I cant get it so I am unable to attach it into headers of my http request.
Also, can I add a coockie with flag HttpOnly using javascript?
HttpOnly means you cannot read it from Javascript on the client but the browser is still aware of that cookie and it is being added to any subsequent request you are making to the server.
It can be useful for an auth session cookie for example.
Session cookies are usually opaque tokens that are meaningless to the user and are meaningful only to the server. Thus there's no real reason why the client code would need to read them
Also, can I add a cookie with flag HttpOnly using javascript?
No
IIUC, when I create a WebSocket an HTTP request is sent to the specified URL, containing an upgrade request. Is it typicaly to pass authentication information along with this upgrade request, or should it be performed separately?
var websocket = new WebSocket("ws://domain:port/foo"); // Can I include authentication headers with the initial upgrade HTTP request?
The WebSocket RFC standard doesn't define any protocol-specific client authentication mechanism but mentions that HTTP authentication is a possible option:
10.5. WebSocket Client Authentication
This protocol doesn't prescribe any particular way that servers can
authenticate clients during the WebSocket handshake. The WebSocket
server can use any client authentication mechanism available to a
generic HTTP server, such as cookies, HTTP authentication, or TLS
authentication.
The standard for http URLs prescribes a form which includes the login credentials within the URL. The form is http://username:password#www.example.com/file. But this syntax is not supported by all browsers because, frankly, it was a really bad idea.
The WebSocket API does not expose any features intended for HTTP client authentication. That means web browsers are supposed to provide authentication the way they usually do: With the URL syntax above when they decide to support it or by showing a popup to the user where they enter their login credentials.
You should do the authentication through web, return a cookie and then connect to the websocket server again, carrying the cookie. The WS server can validate the cookie
If there is no cookie based authentication or it is just not possible (like the WS server in another domain), you will have to create your own request-response messages for login.
I am designing a multi-platform application at the moment (clients would include internally developed mobile apps, and an AJAX heavy javascript client initially) centred around a REST API. Since in the future the API may be open to third parties, I am looking at using OAuth 2.0 for authentication and authorization with the API.
I am trying to get my head around some of the security issues with this arrangement, particularly with regard to the javascript client. I don't want this client to behave like a third party client might, with a whole bunch of redirects and popups and stuff, which is what most OAuth documentation seems to focus on. Since it will be delivered from my own domain, I am thinking that the server side of the webapp can be the actual client, and store the client secrets and refresh tokens, while the javascript retrieves new auth tokens from the server as it needs them.
To put it in step by step form:
The user logs in using non-ajax html form, generating auth and refresh tokens which are stored server side. This sets a HTTP-only login session cookie.
The javascript client code is sent to the user's browser after login.
The javascript client makes a request to a resource that is part of its own application (not part of REST api) to retrieve the token. The session cookie ensures that the client is genuine, and the referer will also be checked. Auth token is returned.
The javascript client validates the token with the REST API.
The client can now use the token to make requests against the REST API until it expires.
If the auth token expires or the page is closed and re-opened, the javascript client can request a new token. The server side of the webapp takes care of refreshing the token and sends the new token, as long as the login session cookie is still valid.
Does this make sense, or would it leave massive holes in the system? In particular, is it insane to have a resource on the web that hands out authentication tokens based on a cookie being set?
Just make sure that any communication to browser is HTTPS, so that no one in the middle can steal your tokens. And set the "secure" flag on your auth cookies.
Most browser authorization schemes nowadays boil down to a session token that's passed in a cookie. The OAuth 2 scheme is a couple steps ahead because a) the tokens (can be) dumb tokens with no dangerous user info inside, and b) they expire.
(Just to put that comment in context: one time I popped open a session token from a site and discovered my home address and phone number was in there. Ack!)
I've seen code that does HMAC signing of requests inside the brower javascript, but it came with a huge disclaimer: don't use this in production. A signing scheme requires the client (javascript) to know a "secret" string, but the browser/javascript is so insecure that it amounts to handing your secret strings to the world.
But if you keep all your commuinication over HTTPS, then you're really just putting an OAuth twist on the familiar scheme of passing session tokens as cookies.
We have a "widget" that runs on 3rd party websites, that is, anyone who signs up with our service and embeds the JavaScript.
At the moment we use JSONP for all communication. We can securely sign people in and create accounts via the use of an iFrame and some magic with detecting load events on it. (Essentially, we wait until the iFrames source is pointing back to the clients domain before reading a success value out of the title of it).
Because we're running on JSONP, we can use the browsers HTTP cookies to detect if the user is logged in.
However, we're in the process of transitioning our system to run realtime and over web sockets. We will still have the same method for authentication but we won't necessarily be making other calls using JSONP. Instead those calls will occur over websockets (using the library Faye)
How can I secure this? The potential security holes is if someone copies the JavaScript off an existing site, alters it, then gets people to visit their site instead. I think this defeats my original idea of sending back a secure token on login as the malicious JavaScript would be able to read it then use it perform authenticated actions.
Am I better off keeping my secure actions running over regular JSONP and my updates over WebSockets?
Websocket connections receive cookies only during the opening handshake. The only site that can access your websocket connection is the one that opened it, so if you're opening your connection after authentication then I presume your security will be comparable to your current JSONP implementation.
That is not to say that your JSONP implementation is secure. I don't know that it isn't, but are you checking the referrers for your JSONP requests to ensure they're really coming from the same 3rd-party site that logged in? If not, you already have a security issue from other sites embedding your javascript.
In any case, the 3rd-party having an XSS vulnerability would also be a very big problem, but presumably you know that already.
Whether you are sent cookies during opening WebSocket handshake by browser (and if so, what cookies) is not specified by the WS spec. It's left up to browser vendors.
A WS connection can be opened to any site, not only the site originally serving the JS doing the connection. However, browsers MUST set the "Origin" HTTP header in the WS opening handshake to the one originally serving the JS. The server is then free to accept or deny the connection.
You could i.e. generate a random string in JS, store that client side, and let that plus the client IP take part in computing an auth token for WS ..