5 ms·
Hacking Slack using postMessage and WebSocket-reconnect to steal your token
- zaroth 10y agoOne of the best vuln write-ups I've read in a while, in that it steps you through how the initial entrypoint was found, and the steps needed to turn that into a dangerous exploit. I think what really makes this writeup worth the read is the insight it shows into the thought process of identifying an interesting bug and weaponizing it. Thanks Frans!
- hubcaps 10y agoThat was a really cool read. It's pretty awesome to see Slack patch it and pay them so quickly, if only all companies could operate like that.
- ridruejo 10y agoIt is not the first one either. The Detectify team is top notch and I don't know how they and their product are not better known
- fransr 10y agoThanks a lot! I had a lot of fun doing it and I really wanted to get every step of the process out there, so that was some really nice feedback :)
- dantiberian 10y agoThe mitigation creating an a element seems a little bit awkward: if (!TS.utility.calls.verifyOriginUrl(evt.origin)) { return } ... verifyOriginUrl: function(originHref) { var a = document.createElement("a"); a.href = originHref; return a.hostname == window.location.hostname }, Is there a JS API for getting the host name from an origin, or is creating DOM elements the way to do this?
- jhgg 10y agoThere's a node module, but this is a quick hack to do it. Relatively low cost if this function isn't getting called too much. Combining this + some basic memoization would probably be the easiest and most performant solution. I imagine you're usually at most receiving events from a single origin.
- rmanalan 10y agoUsing a DOM element is the most efficient way to do this.
- kornish 10y agoMy suspicion is that creating the <a> tag may be more secure because it's implemented at the browser level, below any Javascript which may be running. Probably also more performant. Not sure though.
- timdorr 10y agoNope, you would have to build your own, which is fraught with potential vulnerabilities. While roundabout, this does send you through the browser's own URL parsing and validation, which obviously should be secure and well-tested.
- floil 10y agoevt.origin is already provided by the browser, though. It shouldn't need canonicalization, unless this is some kind of browser compatibility workaround.
- EnigmaticLion 10y agoJust out of curiosity, how long did it take for you to come up with this PoC? From the initial notice that something might be exploitable until you sent the email to slack? Your post makes it look so easy, but it would surely take weeks for me to figure out all these things.
- lightedman 10y agoPersonally, my first clue is that token protection/revocation is rarely implemented properly. It's one of the first things I look at when dealing with a web-based system which is obviously using them.
- fransr 10y agoIt's a common pitfall and easy to look for. The stuff I spent most time with regarding this specific issue was finding the proper event that did something bad.
- homakov 10y agoExposing onmessage wasn't the best idea. Instead it should be something more restrictive with origin check built in. addMessageListener("https://*.slack.com" https://*.slack.com", function(data){})
- scott_karana 10y agoKudos to Slack for the quick fix! I've also been pleasantly surprised by their response times for bug reports, and even feature requests. Wonder if their support team is proportionately larger than most startups, or if "10x Support Agents" are a thing?