Eddie Coldrick

Dashboard Profile Pictures Security Vulnerability

Here's a write-up of a security vulnerability that I found and reported to a company regarding profile pictures

The company I reported this to have asked not to be named in this post, which I have happily respected. The company creates a web platform, where each user has a dashboard and their own profile. Each user can see the profiles of accounts associated with them on the dashboard. This means that users need to see their own profile picture, and the profile pictures of those associated user accounts. They see no other profile pictures when using the dashboard. The user is therefore expected to be restricted to only being able to view these images, or in other words: the principle of least privilege, where a user is only given access to what they need access to in order to do what they need to do.

The Vulnerability

In my spare time, I was taking a look in the Network tab in DevTools. A lot of GET requests are being made to endpoint URLs with user ID entries. Now, I am at a point where I can test all of these endpoints with neighbouring IDs, to see if the IDs are incremental (aka forced browsing). Most endpoints needed the session ID in the cookie; only one instead needed it in a different request header, which I was able to test with some Fetch API jiggery-pokery in the console (aka making a request with the Auth header!). All of them returned errors when using an ID that was not the one of the authenticated user, except for the one to get profile pictures. It was expected that it should return an error on any ID that is not the users, or the ID of an associated user account to that user. But any valid user ID was accepted and the profile picture returned.

Here's an example of what the request to the endpoint looked like:

GET https://example.org/dash/getprofilepicture?userid=xxxx

Why fix it?

By having a combination of incremental IDs and the profile pictures of all IDs being accessible from an authenticated user, it would be very simple to write a script to take all the images and display them on a webpage. Mark Zuckerberg's 'Facemash' comes to mind.

Here's a pseudo-code example of a script that takes the pictures:

set base_url = "https://example.org/dash/getprofilepicture?userid="
set user_id = "001"
set exists = true

while exists:
    set url = base_url + user_id
    send GET request to url
    if response status code is 200:
        display profile picture
        set user_id = zero-padded string representation of (int(user_id) + 1)
        exists = false

KEY green: method, blue: variable, purple: control flow, red: string

This code assumes that the ID is always three characters long. In the loop, the url is constructed using this user_id value. If the response status code is 200, indicating a successful response, the profile picture is displayed and user_id is incremented by 1 and converted back to a zero-padded string representation. If the response status code is not 200, indicating that the user ID doesn't exist, the loop breaks by setting exists to false.

OpenAI's ChatGPT would like me to make sure I let you know that this code was written by them. And that it is pseudo-code, so the implementation will depend on the programming languages and libraries you will be using. Read my full conversation with ChatGPT to get this pseudo-code.


The company were very happy to fix the issue. The endpoint now acts the same as the other endpoints... When authenticated, you can view your own profile picture and the profile pictures of users associated with yourself. An exemplary reponse to a report in my books! Many thanks to the company for their commitment to user privacy and safety.


Monday, January 16, 2023 10:32 GMT

First ticket inputted into support system

Monday, January 23, 2023 09:08 GMT

No response to first ticket. Second ticket inputted asking for acknowledgement.

Monday, January 23, 2023 09:14 GMT

Acknowledgement explaining that they could not find first ticket, even with ticket ID. Asked for further details.

Monday, January 23, 2023 9:19 GMT

I replied with a copy of my first ticket.

Monday, January 23, 2023 9:26 GMT

Company responded asking for my user details

Monday, January 23, 2023 9:26 GMT

I responded with my user details

Monday, January 23, 2023 10:00 GMT

Company acknowledged that it had been raised internally

Monday, January 23, 2023 15:26 GMT

Company responds saying they are looking into it and asking for some more details about my user account/ticket. They also asked, out of interest, how I found the issue.

Monday, January 23, 2023 15:52 GMT

I respond clarifying details and explaining how I found the issue

Tuesday, January 24, 2023 10:08 GMT

Acknowledged that they recieved last email and that how I found the issue was interesting. Explained they were still looking into it.

Wednesday, February 15, 2023 08:12 GMT

Fix published to production environment. Acknowledged via email.

© 2022 Edward JA Coldrick. All rights reserved.

Email: [email protected]