cloud · high

From Finding AWS S3 Bucket to Sensitive Data Exposure

5 min read r29k

How reading a page's source led to an open S3 bucket leaking private files across every organization.

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:

iframe src
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:

page source
"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:

object url
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 cli
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.

more writeups
Escalating Self-XSS to Stored XSS via Image Injection + IDOR Wayback Machine to Account Takeover SSTI to Local File Read
← all writeups