The Trendsale Chronicles: Breaching the admin portal
- Cornelius Reetz & Mohamed Macow
- Bug bounty , Security , Trendsales , Sanitation , Unauthorised access
- February 8, 2024
Finding the domain
In the previous blog post, we discussed how we found a stored XSS vulnerability in the Trendsales platform. This time, we will discuss how we found a way to breach the admin portal of the platform.
For finding the domain, we did a simple subdomain lookup of their main URL, this revealed the URL admin.trendsales.dk
, which we of course started to look at.
Finding the vulnerability for logging in
When we visited the site, we noticed that it was built using react - a thing most people don’t notice is that browsers can actually unpack the react file, and give users the ability to view the source code directly from the react app. This is seemingly also what they forgot at Trendsales.
When looking at the source tree we saw the following:
Looking inside Utils/UserUtils.js
we found the following code:
isValidLoginEmail: (email) => {
return /\S+@((trendsales)|(tradono))\.((dk)|(com))/.test(email);
},
The above code looks if an email is a valid email, and that it ends in either of the Trendsales/Tradono domains. This gave us the idea to intercept a login request and change the email to our own email, and see if we could log in. This worked, which indicated it was a client-side only validation of the email.
However, while we could login and be issued cookies, we couldn’t see any of the admin panels.
Finding a method for accessing the admin panel
Looking into the source-view from before, we noticed that the Utils/Permissions.js
file, looking in this we can see the different permission levels logged, and how the front-end checks for them and changes behaviour.
Going into our local storage, we can thus copy the JSON-string saved under me
:
Copying this, and adding the following field to the JSON: "permissions": 2097152,
, and then replacing
it under local storage again, we now notice that the ”Login” screen disappears and that we have now have
the view of the security dashboard.
While we can’t really do anything here (All we tried to do was search for our own UUID, this returns a 403, therefore we concluded that the Authorization check on the API itself worked, only the frontend was exposed).
Changing our Permissions in local storage, gave us different views of the dashboard.
The Suggested Fixes
Suggestion 1: Validate emails serverside, as well as client-side, before sending the magic-link
Suggestion 2: Serve the dashboard based on API, instead of having it in the client-side code. Could probably do something like making it serverside-rendered.
We have later checked, and suggestion 1 has stopped the logging in with our method, which has prevented us to check whether suggestion 2 was also implemented ;)