How Our CASM Product Uncovered an IDOR Exposing Employee Banking PII

How Our CASM Product Uncovered an IDOR Exposing Employee Banking PII

Modern enterprise applications often consist of dozens of interconnected services, development environments, and staging servers. When these non-production environments are exposed to the internet, they can become a silent liability. In this write-up, we detail how our Continuous Attack Surface Management (CASM) product discovered an exposed staging environment for a major HR and Payroll provider, which subsequently led our research team to uncover a critical Insecure Direct Object Reference (IDOR) vulnerability exposing sensitive banking details.

For confidentiality, the target company's name and specific identifying URLs have been redacted.


The Discovery

The engagement began with our CASM platform continuously mapping the external attack surface of the target organization. During its routine discovery phase, CASM identified an exposed sub-domain: hr.loadtest.[redacted].net and its corresponding API endpoint pay-api.loadtest.[redacted].net.

These load-testing and staging environments are often overlooked by security teams because they are not meant for production use. However, they frequently contain exact replicas of the production application logic and, in some cases, synchronized or obfuscated production data.

Because CASM instantly flagged this exposed environment, our team decided to investigate the application hosted there.


Target Overview

The target application was an enterprise Human Resources Information System (HRIS) and Payroll management platform. We authenticated into the load-testing environment using a provided test account with basic administrative privileges (specifically, a Time & Attendance Admin, but not a full Payroll Admin).

In the application, Payroll Administrators have the ability to view, add, and modify direct deposit information for employees. Our goal was to determine if our lower-privileged account could somehow access this highly sensitive data for other employees.

The employee pay details interface in the HR application

Discovering the Flaw

To understand how the application handles sensitive payroll data, we populated some dummy banking details for a test employee and intercepted the HTTP traffic when the application fetched these details.

Adding direct deposit information for a test employee

When viewing an employee's payment rules, the front-end makes an API call to fetch the direct deposit data:

GET /api/v2/payment-rule/payment-rule-details?selectedEmploymentId=60922&activeEmploymentId=60923&onOrBefore=2025-10-26&withImage=true HTTP/2
Host: pay-api.loadtest.[redacted].net

We immediately noticed the selectedEmploymentId and activeEmploymentId parameters. These numeric identifiers directly referenced the employee whose data was being queried.


The Exploit

The vulnerability arose because the API endpoint lacked proper authorization checks. While the application verified that the user was authenticated, it failed to verify if the requesting user was authorized to view the payroll details of the specific EmploymentId provided in the URL.

We tested this by logging into an entirely different account — one that did not have Payroll Administrator privileges. We then took the intercepted API request and simply swapped the selectedEmploymentId and activeEmploymentId parameters with the ID of our target employee.

GET /api/v2/payment-rule/payment-rule-details?selectedEmploymentId=[TARGET_EMPLOYEE_ID]&activeEmploymentId=[TARGET_EMPLOYEE_ID]&onOrBefore=2025-10-26&withImage=true HTTP/2
Host: pay-api.loadtest.[redacted].net

The server responded with a 200 OK and returned the full JSON payload containing the target employee's sensitive banking information:

JSON response leaking sensitive bank account details

Impact

By simply iterating through employment IDs, an attacker with any valid account could systematically harvest the financial data of every employee in the system. The leaked Personally Identifiable Information (PII) included:

  • Bank Name
  • Bank Account Number
  • Routing Number
  • Account Type (Checking/Savings)
  • Effective and Expiry Dates
  • Internal Check File Names

In a production scenario, this data could be exploited for direct financial fraud, targeted phishing, or sold on the dark web.


Root Cause and Remediation

The root cause of this vulnerability is a classic Insecure Direct Object Reference (IDOR), compounded by the fact that the vulnerable endpoint was exposed in a forgotten load-testing environment.

To remediate this issue, we recommended two primary steps:

  1. Implement Object-Level Authorization: The API must perform a backend authorization check for every request to ensure the authenticated user has explicit permission to access the requested EmploymentId. It is not enough to hide UI elements; the API itself must enforce access controls.
  2. Restrict Non-Production Environments: Staging, UAT, and load-testing environments should not be publicly accessible. They should be placed behind a VPN or strictly IP-allowlisted.

This finding perfectly illustrates why continuous attack surface monitoring is essential. Even if the production application is thoroughly tested, a forgotten staging environment running older or misconfigured code can provide attackers with a backdoor into your sensitive data.

Centralise your Appsec

A single dashboard for visibility, collaboration, and control across your AppSec lifecycle.

Explore Live Demo

Read more