Hello everyone, hope you're all doing well. In this one I'll share how I found an AWS S3 bucket and how it led to leaking sensitive user data. The program was a helpdesk app with features for hiring new employees, assigning tasks, preparing presentations, and so on. I spent a while just getting to know the app, what it did and how it worked, then started testing each feature one by one.
The feature
The one I focused on was presentation preparation, where an employee can practice and prepare a presentation. They can upload documents like slides or PDFs, and add sticky notes that stay private to them. They can also deliver the presentation from here: hit start, and only their slides or PDFs are shown to others while the notes stay private. The whole section is private, and files are scoped per organization, a file uploaded in one org should never be reachable by a user in another.
Finding the bucket
Going through the page source, I noticed the app loaded the slides in an iframe. The URL looked something like this:
https://cdn.example.com/document/view.html?id=91929&pages=1&s3=bucket-name-us-east-1
Some interesting parameters there. I opened the URL in a new tab and got a blank white page. My focus was on the id parameter, so I swapped it for another document id to see if I could reach someone else's, but it returned the same blank page. At this point the s3 parameter still hadn't caught my attention.
Then I opened the source of that page and spotted an interesting line of JavaScript:
"canonical_url" : "https://bucket-name-us-east-1." + s3.amazonaws.com + "/document/" + ID + "/result.pdf",
I pieced the endpoint together with an ID value, and it became:
https://bucket-name.us-east-1.s3.amazonaws.com/document/12345/result.pdf
Opening that gave me a NoSuchKey error. But when I simply opened the bucket root, it greeted me with a public listing. The first file was Admin_audit.zip. I thought I'd hit a goldmine, but after downloading and unzipping it, there was nothing sensitive inside.
Digging in with the AWS CLI
The browser view of the bucket is confusing, so I switched to the AWS CLI for a proper look:
aws s3 ls s3://bucket-name/
It returned six directories. The first, Admin_reports, held that audit file, nothing sensitive. The others, Documents, Notes, Pins and Pictures, were a different story.
The data exposure
The Documents directory held every presentation file users had uploaded. As I mentioned, those files were supposed to stay private until the user started their presentation, and even then they should never cross organization boundaries. Here, files from every organization were exposed together. Notes held the private sticky notes of users across all orgs, and Pins and Pictures leaked private data too. The one saving grace was that the bucket had no public write access.
Takeaway
Checking an S3 bucket for a misconfiguration takes a minute. The real work is finding the bucket in the first place. This was my first S3 bug, and I found it just by reading a page's source code. Thanks for reading.
Any questions? Reach me on Twitter, @R29k_. See you in the next one.