Insecure use of unique identifiers

In March 2020, our team started a couple of security research projects including participating in bug bounty programs, looking at IoT devices, and passively looking at mobile apps that have weak authentication and authorization controls.

We came across one app called Remind, which is used by one of our team members to interact with their toddler’s school. It is designed to provide a private mobile messaging platform and virtual classroom allowing teachers, students and parents to interface with one another through instant messaging. While the app is normally used to delivery material (e.g., homework) to students, a key feature we looked at was sending photos (insert problem).

Note: On May 29, 2020, Proack confirmed that Remind has implemented mitigation controls (pre-signed URLs) to protect data shared on their platform.

The Problem
Before we break down the problem, one thing we want to point out is that this issue is not unique to Remind. We found 7 vendors over a 2-week period that were making the same mistake. Of the 7, only Remind and 2 others have implemented a fix.

So herein lies the problem. Any time a photo or file was uploaded to Remind’s AS3 (Amazon S3) bucket and distributed to recipients, a PRNG (pseudo-random number generator) was used to create a unique identifier, which was then associated to the image stored in AS3. In addition, when the photo was uploaded, it was written with “public access”, allowing anyone with the URL to access it. Developers had made the assumption that the uniqueness of the identifier was sufficient enough that validating the user’s access was not required. With no authorization check, once you had the URL, you had the data indefinitely.

In our research, we found a variety of different methods that developers were using to “secure” data uploaded or generated on their platform. Some used UUIDs or PRNGs, while others used sequential numbers. In one case, we found a company using the customer ID, followed by the numerical upload date (YYYYMMDD), and a sequential 6-digit number (we will update this post once these vendors have implemented fixes).

Now an attacker could theoretically attempt to “guess” the identifier (probably an exhaustive and painful effort), but an easier approach could be to pull them from a victim’s browser history, or grab them from server, proxy and referer logs.

If you are a penetration tester, this likely sounds all-too-familiar to CWE-598: User of GET Request Method With Sensitive Query Strings.

Using Remind, here is a sample file we sent and accessed it through CloudFront and directly from Remind’s AS3 bucket:

File is uploaded to the AS3 bucket with the ACL value of “public-read”
File is uploaded to the AS3 bucket with the ACL value of “public-read”.
File has successfully been written to the AS3 bucket, and AWS responds with the uploaded file’s URL.
File has successfully been written to the AS3 bucket, and AWS responds with the uploaded file’s URL.
Unauthenticated request to download the file through CloudFront.
Unauthenticated request to download the file through CloudFront.
Downloading the file directly from the AS3 bucket without being authenticated.
Downloading the file directly from the AS3 bucket without being authenticated.

Here is a sample GET request to CloudFront to grab a photo that was shared through Remind. Note, there is no cookies or tokens submitted with the request.

Rendered image retrieved through CloudFront without being authenticated.
Rendered image retrieved through CloudFront without being authenticated.

Below is a list of companies/industries we contacted as part of our research:

CompanyData Exposed
RemindPhotos and files shared through the platform
Retail (1)Customer photos
Retail (2)Customer photos
Retail (3)Customer photos
Photo Sharing/RetailerCustomer photos. Even if you delete your photos they are still saved and exposed indefinitely.
Retail (4)Customer photos
TravelCustomer PII

Recommendation

For applications that do not use cloud storage solutions, implement validation checks to ensure resources are only accessible to authorized users.

If cloud storage is used, avoid writing data with public access, and utilize authorization controls such as expiring pre-signed URLs to restrict access to resources. We have also found organizations that enforce user authorization by “proxying” the resource access request through their own servers and only allowing their systems to access the cloud storage account directly.

Disclosure timeline:

CompanyTimeline
Remind• April 10, 2020: Sent an email to a security mailbox at Remind indicating we wish to responsibly disclose a vulnerability on their platform
• April 13, 2020: Sent a follow up email requesting a response and some urgency to be applied as photos of minors are exposed on the platform.
• April 15, 2020: Remind accepted our findings and were reviewing possible fixes/mitigations that could be implemented.
• April 21, 2020: Proack and Remind mutually agreed on a public disclosure deadline.
• May 19, 2020: Remind confirmed an update was made to the platform to use URL signing.
• May 28, 2020: Remind confirmed all old links have been updated to use the revised data model.
• May 29, 2020: Proack confirmed the vulnerability has been mitigated with URL signing.
• July 7, 2020: Public release. Remind blog post
Retail (1)• May 4, 2020: Reported findings to retailer indicating the photos uploaded to their platform are exposed.
• May 4, 2020: Findings were accepted by the retailer and indicated the issue was previously identified as part of a previous penetration test; however, based on the number of possible UUIDs, the vulnerability was deemed low risk.

<still pending resolution>
Retail (2)• April 24, 2020: Proack reported the findings identified on the retailer’s platform, indicating customer photos uploaded to the platform were not secured.
• April 25, 2020: Retailer accepted the findings and is in the process of reviewing the identified vulnerabilities.
• May 15, 2020: Sent a follow up email requesting an update.
• June 2, 2020: Sent another follow up email requesting an update.
• June 2, 2020: Received a response indicating there was an internal mix up at the organization and Proack should expect a response.
• June 4, 2020: Retailer requested a copy of our report again. Report was resent.

<still pending resolution>
Retail (3)• April 17, 2020: Findings reported and accepted by retailer.
• May 27, 2020: Retailer remediated the identified vulnerability.
Photo Sharing/Retailer• April 23, 2020: Reported findings to organization
• April 24, 2020: Organization rejected the finding due to the complexity of the identifier used.
• April 24, 2020: Additional information was provided to the organization outlining the predictability of the identifier used.
• May 1, 2020: Organization accepted the finding and indicated they are aware of the issue.

<still pending resolution>
Retail (4)• May 4, 2020: Reported findings to the retailer
• May 5, 2020: Retailer accepted the finding and confirmed a fix is being explored.
• June 2, 2020: Requested an update.
• June 3, 2020: Retailer is still in the process of remediation. Does not expect remediation to be completed before July 1st, 2020.

<still pending resolution>
Travel• April 22, 2020: Finding reported and accepted by organization.
• April 27, 2020: Finding was confirmed remediated.