How We Discovered a Broken Authentication Flow in a Financial Dashboard

HACKADEMY'S HACKS

W.Ighodaro

5/1/20263 min read

A client reached out to us after noticing something strange inside their internal financial system. One of their staff members reported that while navigating the dashboard, they briefly saw data that did not belong to them. There was no alert, no crash, and no obvious breach. Everything looked normal, but that single observation was enough to raise concern. That is when they brought us in for an authorized security assessment.

When we got access to the application, we approached it the same way a normal user would. We logged in using the test credentials they provided and began moving through the dashboard slowly. At this stage, we were not trying to break anything. We were trying to understand how the system behaves under normal conditions, because that is where most logic flaws hide.

We started by observing how the login request works and how the system manages sessions.

The application issued a session cookie after login, which is expected. At first glance, it looked properly configured. The cookie was marked as HttpOnly, which helps reduce client-side attacks. But security is not just about flags. It is about how the entire system uses that session.

After logging in, we explored the dashboard and quickly noticed that user data was being loaded based on a parameter in the URL. That immediately caught our attention.

We decided to request our own dashboard data directly to see how the backend responds.

At this point, nothing looked wrong. The system returned the correct user information tied to our account. But the presence of the user_id parameter raised an important question in our mind. Is the backend verifying that the logged-in user is allowed to access that specific ID?

Instead of guessing, we tested it carefully. We changed the user_id to a different value.

That was the moment the issue revealed itself clearly. The system did not check whether we were authorized to access that data. It simply trusted the user_id parameter in the request. That means any authenticated user could access any other user's financial data just by changing a number.

We paused here and analyzed the situation carefully. This was not a failure of login or authentication. The system correctly identified that we were a valid user. The real issue was authorization. The system failed to enforce who can access what.

To understand the scale of the problem, we performed a controlled test by requesting multiple user IDs within a safe range.

At this stage, it was clear that the vulnerability affected the entire user base. Any logged-in user could enumerate and access sensitive financial information across the platform without restriction. There were no alerts triggered, no logs highlighting unusual access, and no protections in place.

We documented everything carefully and moved into the reporting phase. We explained to the client that the root issue was a lack of server-side authorization checks. The application relied on user-supplied input instead of enforcing access control based on the authenticated session.

The fix was straightforward but critical. The backend must ignore any user ID coming from the request and instead derive the user identity directly from the session. Every request must be validated to ensure the user is only accessing data they are permitted to see.

We also advised them to implement monitoring for unusual access patterns, such as rapid requests across multiple user IDs, which could indicate abuse.

The outcome was positive. The client patched the issue quickly, added proper authorization logic, and improved their logging system. What could have turned into a serious internal data breach was stopped early.

The biggest lesson here is something I always emphasize. Logging in is not enough. You must always control what a user can access after they log in. Many systems fail not because attackers are highly skilled, but because simple logic checks are missing.

In conclusion, security is not about adding features. It is about thinking deeply about how those features can be abused. That is what separates a secure system from a vulnerable one.