7 ms·
Hidden in plain sight: Brute-forcing Slack private files
- thom_nic 11y agoGithub does something similar, if you drag an image into the textarea in their issue tracker, it uploads the image to (I think) a public URL. I've considered what this could mean for teams with private projects who might e.g. attach screenshots with sensitive information. Here's an example of an image uploaded via the GH issue tracker. Definitely public. https://cloud.githubusercontent.com/assets/95562/7319912/2004f03a-ea67-11e4-852f-f558af75b078.gif https://cloud.githubusercontent.com/assets/95562/7319912/200...
- willvarfar 11y agoThe good news is that github puts a uuid in the url, so its unguessable. Slack, on the other hand, didn't have a big unguessable number... they had a very small number you could brute-force.
- BillinghamJ 11y agoUUIDs are (usually) generated in a systematic fashion, so large parts of them are often possible to determine ahead of time.
- mikeash 11y agoCareful, being unguessable is not one of the properties required of a UUID. All a UUID guarantees is that two UUIDs generated by the specified procedure will never match, even if they're generated by different computers not in communication with each other. But it does not guarantee that an attacker cannot generate the same UUID generated by somebody else if they follow a different procedure. It's the difference between avoiding collisions between cooperating entities, and avoiding collisions from malicious entities. For example, a version 1 UUID is just the combination of the computer's MAC address and the current time. This is sufficient to guarantee uniqueness (as long as you don't duplicate MAC addresses, and you wait at least 100 nanoseconds between generating successive UUIDs) but will be pretty easy to guess if you have a rough idea of when the UUID was generated and which manufacturer might have made the NIC on the machine where it was generated. More abstractly, a version 4 UUID is just a couple of identifying bits and 122 random bits, but the nature of the random bits is not specified. Your UUID generator may well use a PRNG that is not cryptographically secure, which could still be good enough for cooperative uniqueness, but not good enough to avoid predictability. (For example, a PRNG seeded with the machine's MAC address and boot time would fit this.) In short, don't rely on a UUID being secret unless you know exactly how it's being generated, all the way down to the underlying random number generator. And if you're going that far, you might as well just read 16 bytes from /dev/random and be done with it.
- willvarfar 11y agoThe github sourcecode is not open-source, but they've open-sourced a lot of other code in which they seem to be using Ruby's `SecureRandom::uuid()` function in the same kind of context for generating what they term 'opaque ids'.
- sebak 11y agoThe problem is not with having public urls. The problem is with public urls that don't have enough random numbers or if these numbers aren't generated by a CSPRNG.
- arethuza 11y agoDoesn't help how complex your URL is if legitimate users can pass it to anyone else who can then access the file without proper authorization.
- heydenberk 11y agoIt does help. Malicious users intending to share files can do so without having a public URL.
- mikeash 11y agoPreventing legitimate users from sharing the data with malicious users is essentially what DRM is, and as we all know DRM is never perfect and rarely any good at all. It's much more important to prevent malicious users from being able to access these files without the help of legitimate users. Which seems like an obvious thing to do, but it's what Slack has failed at here. It's impossible to tell from that one GitHub URL whether they get this right or not.
- NKCSS 11y agoDamn, over a year to fix this? It's good that they did in the end, but the timeline is just crazy.
- elcct 11y agoMaybe someone needed time to brute force all those tasty files hanging around ;)
- wtbob 11y agoThe correct answer for using URLs as capabilities (which is what a 'secret URL' really is: a capability to a resource, which can be handed out, copied &c.) is to use a 256-bit value as part of the URL. Thus, rather than 'http://example.invalid/TEAM-DOC-SHORT-RAND/' http://example.invalid/TEAM-DOC-SHORT-RAND/' use 'http://example.invalid/w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI' http://example.invalid/w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxT.... If you're really paranoid, double the length. I guarantee it won't be guessed, in either case.
- Lazare 11y agoYes, exactly this. It's not rocket science; it's odd how much effort Slack put into implementing (and then reimplementing in a slightly less broken fashion) a clearly wrong solution.
- relaxnow 11y agoDon't forget that it should ideally be cryptographically random. If the sequence is predictable (like based on an auto incrementing number or on time) then you might still be able to guess a 256-bit number.
- wtbob 11y ago> Don't forget that it should ideally be cryptographically random. I thought that went without saying, nut yes, it must be cryptographically random (not ideally—it must be).
- evancordell 11y agow3 has some guidelines on capability urls: http://www.w3.org/TR/capability-urls/ http://www.w3.org/TR/capability-urls/
- tlb 11y agoThe guideline for unguessability in that TR just says to use a UUID. UUIDs are ugly, and quite long for the amount of randomness they contain. I prefer Slack's new 10*base36 solution.
- dantillberg 11y agoSummary from my read of this: (the article does a great job of couching the process of exploiting this, as well as motivating why these numbers are too low, but here are the vulnerabilities...) - Slack chose to use a 6-hexadigit/24-bit "secret code" as the only/final code required to download "privately" shared files. That's way too short; people have botnets almost that big, such that even aggressive IP-based rate-limiting wouldn't stand a chance. They might have also made these fairly common mistakes (which served to compound the vulnerability): - Returning different/distinguishable error codes when the request matches correctly on some parts but not all. This allows attackers to guess each in turn. - Considering values such as the "file ID" to provide additional security/entropy, when in fact these IDs are generated semi-sequentially, and thus a moderately-sophisticated attacker can narrow the search space dramatically. - Considering values such as the "filename" to provide more security/entropy; however, you can make no guarantees about the length or uniqueness of filenames, so you shouldn't consider that a security feature at all.
- joshstrange 11y agoAlso important to note it took Slack over a year to fix this issue often with long stretches of silence even with requests from the bug hunter.
- jwilkins 11y agoInterestingly, I put the same bug in at HackerOne 9 months ago. It was closed as not applicable. So they had at least two independent reports of the same bug and failed to understand it, acknowledge it and then fix it. Way to go slack. If you have any critical data passing through slack, when you get owned, you won't be able to say say it wasn't entirely preventable.
- jwilkins 11y agoOne thing I can add from my analysis is that there aren't seperate counters for files/teams/etc. there's only one. So if a given id is used by a team, it won't be used as a file id.
- delinka 11y agoThis should indeed inform potential users of additional security risks of using Slack, especially for communication of corporate confidential information. That said, this isn't a realistic threat to my own social use of Slack.
- thmpp 11y agoThe best part of the story actually comes at the end, back-and-forth messaging with slack about the bug report
- braum 11y agodefinitely, I'm disappointed with slacks responses. We did a trial and have had some correspondence with their support team which has been excellent to date. So I assumed they were above some of this silicon valley elitism. I'm glad to see this kind of public disclosure. We have been a customer since that initial trial, we stopped using hipchat.
- relaxnow 11y agoTo be fair, most of the bad correspondence was from 2014. Their new representative 'Leigh' appears to be doing excellent work. Also we're still happy users of Slack, I would just never trust them with secrets :-).
- kordless 11y ago> We apologize for the delayed reply. We track these issues via our internal bug system, and only reply to the reporter once the bug is resolved internally. We generally ignore messages asking for updates, as we receive a high volume of these (even for non-issues). This rationalization is illogical, which usually means someone is in conflict. From a logical standpoint, externally, it could be they are fixing something OR don't know about it OR don't care. Given the conflicting rationalization, I'd say they didn't know about it and then made up an excuse instead of owning it.
- relaxnow 11y agoIt probably means that they're not prioritising vulnerability reports. Which is their prerogative honestly, but it doesn't make researchers happy to work with you. The biggest 'fault' here I think lies squarely with HackerOne. They should've enforced their own guidelines and given me the option to publish in their system after 180 days. But I still don't have that option.
- arice 11y agoGreat feedback, thanks. The 180 day guidance you reference falls under a "Last Resort" clause when "... the Response Team [is] unable or unwilling to provide a disclosure timeline". (which, at first glance, might not have been the case here?) These "Last Resort" scenarios have not yet been fully codified. As a safety precaution, the workflow is still initiated manually with support as these scenarios are extremely rare and littered with edge cases. We've been learning a lot from studying disclosures like this one and you can expect to see the "Last Resort" workflow codified in the product in the future. Now that the report has been Resolved, you should see the normal disclosure options available. Please always feel free to send me a note if you have any questions or feedback on our disclosure workflows - especially if we don't support your preferred route.
- wahsd 11y agoDude! You have got to take a better profile picture. Really? Smug eastern block open collar look with an earbud in? No good. No good at all.
- relaxnow 11y agoHeh, well it is an old picture, I'll see if I can't get a better one made. I didn't join IT for my looks though so hopefully it doesn't stand in the way of your enjoyment of the content.
- wahsd 11y agoNo, it doesn't. I was just kidding. It was the first thing that caught my eye. No worries, it seems the white-knight brigade is out to defend your honor though.
- dang 11y agoI thought it was pretty obvious that you were just kidding, but it's the sort of comment that is hard to interpret correctly, and anyone who missed the jovial tone would have thought it was pretty mean.
- jkern 11y agoSimilarly to using a hash function that is purposefully slow, wouldn't it be a good idea to introduce some artificial latency when responding to requests for urls like this?
- tptacek 11y agoWhat kills me is that this seems like such an unforced error. Just make 256-bit random tokens. They're private URLs. Who cares how ugly they are?
- qyv 11y agoNot to mention making public file sharing explicit instead of implicit, or at least giving the option to exclude specific files from a public URL.
- macNchz 11y agoIf I were responsible for security at Slack, the thought of potentially leaking uploaded files like this would keep me up at night. Slack has gained such wide adoption-think of the things that people are sharing with their coworkers all day, every day. Someone with ill intent could have found so many valuable things.
- fishtoaster 11y agoThis reminds me of my experience with Imgur's private images. A few years ago, I wrote a little js tool to browse random Imgur images by guessing their urls (i.imgur.com/<5-digit code>) until it found one that succeeded. It would add the found image to an infinite-scrolling page. It was kinda fun to browse, and a lot of people seemed to enjoy playing with it. After a couple years, though, Imgur suddenly started blocking access to their images on my site. It turned out they were blocking based on the referrer header. I emailed them asking what was up, and apparently they were attempting to ensure the privacy of public-url images by manually going after any tools like mine (if you google 'random imgur', you'll find dozens). I didn't bother circumventing this, I didn't want to be a jerk just to prove a point. I did try to point out that there were a number of ways to get around something as simple as a referrer block, but I don't think the customer support person I was dealing with was really interested in discussing the issue and I let it drop.
- Drdrdrq 11y agoI had a similar experience, though I was on the other side. Under brute force login attack IT guy suggested I change login HTTP method from GET to POST (which is more appropriate anyway). While I agreed with him that this is better, I pointed out that this is very easy to circumvent. However he proved me wrong - the attacks stopped after that (and I am quite sure it is not because they gained access). Not all attackers are very determined...
- the_wolf 11y agoSimple how-to instructions: 1. log into slack 2. share a private file 3. go to: > https://api.slack.com/web https://api.slack.com/web 4. generate API token 5. copy the link to your private file, and paste as plain text. 6. a file id is in the link, somewhere 7. try out the file id by visiting links like: > https://slack.com/api/files.info?token=#secret!&file=????????? https://slack.com/api/files.info?token=#secret!&file=???????...? 8. see also: > https://api.slack.com/methods/files.info https://api.slack.com/methods/files.info 9. in the JSON output you will CTRL+F to see an address like: > https://slack-files.com/#########-?????????-!!!!!!!! https://slack-files.com/#########-?????????-!!!!!!!!! 10. slackbot warns you, and only you, once and only once that someone found that link. this notification may get buried, or forgotten about. it is your only chance to revoke the public link. 11. if you forget about that link, and it goes viral with millions of visits, lots of luck gentlemen!
- wzm 11y agoDo a google search for site:https://s3.amazonaws.com/uploads.hipchat.com/ https://s3.amazonaws.com/uploads.hipchat.com/ , Atlassian does the same thing, and hasn't really addressed customer questions about it for a long time. https://help.hipchat.com/forums/138883-suggestions-ideas/suggestions/5985543-sent-files-should-not-be-public-amazon-s3-links-t https://help.hipchat.com/forums/138883-suggestions-ideas/sug... is a long running Atlassian support ticket for this.
- rhuddleston 11y agoI see slack now has the option "Disable public file URL creation" Now no-one can share files publicly in our companies slack channels