anshuman_bh reported a bug to Slack.
Hello,
Slack users are allowed to share files (posts, snippets) with other users and within channels.
When a file is shared in a channel and unshared again, it is clearly mentioned on the website that:
Un-sharing the file will not remove existing share and comment messages, but it will keep any future comments from appearing in the channel.
This makes it obvious that on sharing and then unsharing a file within a channel, it will still remain shared and can be viewed by others on that channel. This is the way it is supposed to be.
Now, when a file is shared with a Slack user, currently, there is no way to unshare it again from the UI. But, this can be easily done by sending a request to thehttps://<domain>.slack.com/api/files.unshare end point instead of thehttps://<domain>.slack.com/api/files.share end point. It is as simple as that. When a file (created by say Bob) is unshared from a user (say Alice) by sending the request to the files.unshare endpoint, Alice is not supposed to view that file anymore. It also disappears from Alice's account and if Alice tries to access the old link of that file, she will not be able to view it.
However, it was observed that this can be bypassed.
When Bob first shares the file with Alice, Alice can view this file at a URL that looks like:https://<domain>.slack.com/files/<bob>/<file-id>/<file-name>. Lets call this URL1.
Alice can also view this file listing by directly navigating to https://<domain>.slack.com/files.
Alice looks at the response HTML for the files URL and notices that there is a parameterpermalink_public associated with the shared file. This looks like:\"permalink_public\":\"https:\\/\\/slack-files.com\\/<team-id>-<file-id>-<random-value>\" in the response. She grabs this value and stores it. Lets call this URL2.
So, technically Alice can also view the shared file by navigating to the URL2.
Notice how both the URLs (URL1 and URL2) mentioned above are different.
Now, when Bob unshares the file from Alice (by sending the request to files.unshare end point as discussed above), URL1 becomes unaccessible. But, URL2 is still accessible. And, this is where the problem lies.
So to summarize, lets consider the following scenario:
But, this does not end just yet.
So, Bob then refreshes his files page and notices that his private file has been made public now without his knowledge. This happened because Alice navigated to URL2. He starts freaking out. Bob then revokes this file again from being public and is now confident that it cannot be accessed anymore.
This is partly true because when Alice tries to access the URL2 again, she cannot view the file anymore for obvious reasons because that public URL was revoked by Bob and this generated a new public URL for the file which Alice cannot find out anymore because it is not shared with her.
However, it was observed that this can be bypassed as well.
Alice simply goes to the team's domain https://<domain>.slack.com/and notices that the shared file is still visible on the right hand pane under All File Types. Bob goes ahead and makes some more changes in his private file assuming nobody can access it anymore. But, even though Alice cannot directly view the file via any URL, every time she refreshes her homepage, she will see the updates to the file on the right hand pane.
Remediation
I believe the fundamental problem here is that the permalink_public URL is generated and returned in the response. This is totally unnecessary. If this can be avoided, Alice wouldn't have access to this URL and it would stop any unauthorized access to private files. For the second problem where refreshing the UI was still showing changes for the revoked file, I believe it should not be shown on the UI at all once it has been revoked.
Cheers,
Anshuman
anshuman_bh posted a comment.
I have tried to make a video to demonstrate both these issues - https://www.youtube.com/watch?v=-l0aNVdbyas
The volume is kind of low and the video is long ~ 9 mins Sorry :(
The second issue can be a bit tricky to reproduce so hopefully the video will be helpful.
rhuber closed the bug and changed the status to Not Applicable.
Thanks for your report. Very detailed.
The unsharing works the way you have observed by design. Once a file is public, it remains public unless it is deleted. The purpose of unsharing is not to make a file private, but to stop further comments on the file from being mentioned in the channel where it was shared.
There is a way to access this via the UI. Clicking the red (-) next to the shared channel name calls 'files.unshare'.
Please let us know if we have missed anything here.
anshuman_bh posted a comment.
I think you have not read the report completely.
I clearly mention that un-sharing is allowed for channels but not for users. There is no option to un-share from a user once its shared. Would you mind reading the report again? or Checking the video I sent?
anshuman_bh posted a comment.
The unsharing works the way you have observed by design.
By design, a user is supposed to unshare a file shared in a channel but a user is NOT supposed to unshare a file shared with a different user. The difference between sharing a file in a channel and sharing a file with a different user is important to note here. The (-) sign that you talk about below appears for files shared in channels but does NOT appear for files that are shared with different users. At least, I could not see it. Please correct me if I am wrong. I must be really blind if that's the case.
Once a file is public, it remains public unless it is deleted.
Okay, then why can't the user access the file when its unshared? I clearly show it in the PoC above. See the video if you want further proof. According to what you're claiming, when unshared, the file should still be accessible but not allowed to be commented upon, right? That's not the case here. When I unshared the file (that was shared with a different user), the other user wasn't even able to access the file anymore. How is it public? Do you mind explaining this?
The purpose of unsharing is not to make a file private, but to stop further comments on the file from being mentioned in the channel where it was shared.
You have clearly mentioned here that the purpose of unsharing is to prevent further comments from being mentioned in the channel. But, that is not what the report is about. The report is about files that are shared with other users and not in channels.
There is a way to access this via the UI. Clicking the red (-) next to the shared channel name calls 'files.unshare'.
Again, as I mentioned above, this option does not appear for files shared with different users. So, I am not sure what you are referring to here.
Due to the reasons noted above, I feel that you haven't even read the report properly and yet you call it detailed. You haven't watched the video either because I am keeping a track of viewers. I don't understand the point of having a bug bounty program when you guys don't even read what is being reported specially after I made sure I provided a detailed report and a working PoC. This is disappointing to say the least!
If you still feel this is N/A or Invalid and if I don't hear anything here back within a week, I am going to blog about this.
Let me know if you have any questions.
-Anshuman
kflynn posted a comment.
We spent time reproducing the issue you mentioned, but misunderstood what you were reporting. We take these reports seriously, and investigate every report to the best of our ability.
When investigating the issue, we looked at of the places where files.unshare was called in our apps. The webapp code revealed that it was only used for unsharing a file from a channel (not other users). This is where we made the assumption that you were referring to the files.unshare in regards to channels. This investigation involved a discussion about how sharing works (once public, a file remains public). It was thought that you were reporting something that could affect our users, which we take very seriously.
Calling an undocumented API method may have unexpected results, and we make no claim that files.unshare does anything with regards to files shared directly between users. There is no equivalent UI element in any of our clients that would call files.unshare in this fashion. If this was a feature of Slack, we would absolutely consider it a vulnerability.
We appreciate the effort you put into producing this report, but unfortunately it does not qualify as a vulnerability under our bug bounty guidelines.
anshuman_bh posted a comment.
I am not surprised by the above explanation at all. Not documenting something yet providing that feature silently, I believe, falls in the grey area where it can be argued both ways. And, I definitely don't want to get into that discussion.
And, I wasn't looking for a bounty or anything in the first place. I was just reporting a security vulnerability. I totally respect your guidelines and your decision whether to reward something or not. That is something you guys decide and I have no qualms with it.
but unfortunately it does not qualify as a vulnerability under our bug bounty guidelines.
I don't necessarily agree with this statement. This is indeed a security vulnerability which I think you have agreed above. It is just that it is not reward-able. But, I wasn't concerned about that in the first place. I was just disappointed to see the initial reply. But, I am glad you guys looked at it again and understood what was being reported.
I am giving you a heads up that I will be blogging about this sometime today.
Thanks for your time.