PENETRATION TESTING

The Doors Nobody Locked: A Season of Breaking Things Responsibly

A quarter of black-box penetration testing across fintech, lending, and consumer platforms: six recurring vulnerabilities — IDOR, exposed secrets, broken authorization — and how to fix them.

When humans create something with thorough research and sustained effort, they hold a firm belief that it will overcome every obstacle in the way to serve the goal. The same conviction drives platforms designed to simplify modern life systems built with our data, meant for our protection. Yet in that process, something essential is often overlooked: protecting that data itself and therein lies the failure.

Every system believes it's secure right up until someone asks it a rude question. This quarter, we asked a lot of rude questions, of lending platforms, of trading and KYC systems, of consumer apps handling money and identity at scale. We went in with no credentials, no insider access, nothing but curiosity and a terminal.

What we found wasn't exotic but something we frequently encounter. There was no zero-day lurking in a kernel, no cryptographic weakness that took a research paper to explain. What we found were doors, ordinary, unremarkable doors, that nobody had bothered to lock. An API that would hand over anyone's record if you simply asked for the next number. A key left in plain sight inside a website's own source code. A login flow that never checked whether the person logging in actually was who they claimed to be.

Before we walk through what we found, there's something that needs to be said about how we tested. How you conduct security research matters as much as what you discover. Every engagement we conducted followed a strict non-destructive posture. We enumerated enough to prove a vulnerability existed, but never enough to exploit it at scale. No real user was contacted. No account was wasted beyond the minimum needed to demonstrate impact to the organization involved. In every single case, findings were reported directly to the affected team with a clear reproduction path and a prioritized list of fixes, not published, not sold, not left lying around. Responsible disclosure isn't a compliance checkbox you mark off. It's the difference between a researcher and an intruder who happens to write reports.

We identified six core vulnerabilities across lending platforms, trading systems, and consumer applications. Our team analyzed each to understand the patterns running through all of them. Every identifying detail below has been generalized or stripped. This isn't about naming names; it's about the mistakes repeating across the industry.

1. The Sequential ID Problem

Loan applications on one platform were accessible through simple HTTP requests using sequential numeric identifiers. We started with a debug customer ID discovered in the production JavaScript bundle and enumerated neighboring values.

The platform returned complete records for 40 out of 100 consecutive customer IDs tested. Each record included:

  • full customer name
  • email address
  • phone number
  • loan amount requested
  • amount approved
  • lending partner name
  • medical/retail procedure type
  • application status

At this 40% hit rate, the platform's reported 3 million active customers suggests approximately 1.2 million records are extractable. At 10 requests per second, exfiltration of the entire database would complete in approximately 3.5 days. The endpoint had no rate limiting.

2. Secrets Embedded in Client-Side Code

The production JavaScript bundle contained hardcoded credentials:

  • production backend authentication pair
  • five Azure API Management keys
  • JWT signing key
  • five per-application checksum keys

We verified these were active in production and that the backend accepted requests authenticated with them.

Any browser visitor can retrieve this bundle. CDNs cache it indefinitely. Archive services preserve it. Once published, credentials are permanently compromised and must be rotated immediately.

3. Authentication Without Authorization Validation

The platform's authentication endpoint issued valid JWT tokens without verifying that customer IDs existed or that phone numbers matched database records. We submitted 100 requests with sequential IDs and malformed phone numbers. All 100 returned valid tokens.

When used to request data, 40 returned complete profiles. The authentication layer had already issued tokens before discovering the user didn't own the data. The server validated the request was well-formed but not whether the user had permission to access it.

4. Weak Integrity Checks

Request integrity was supposedly protected by checksums computed on the client side. Both the checksum algorithm and the signing key were visible in the public JavaScript bundle. We reverse-engineered the formula, computed valid checksums for arbitrary customer IDs and dates, and the backend accepted all of them.

A checksum provides no protection if the attacker possesses both the algorithm and the key. Only server-side signatures using secrets unknown to clients provide actual integrity.

5. Exposed Administrative Infrastructure

One platform had database servers directly accessible from the internet on port 1433 with plaintext credentials stored in configuration files. Another exposed source code repositories through accessible .git directories, leaking Firebase Admin SDK keys, payment gateway credentials, and email API keys.

A third platform shipped mobile app credentials hardcoded in the binary—credentials that cannot be rotated without redeploying to all users. One platform exposed 15,284 member profiles including bank account numbers through sequential enumeration, with Google indexing confirming public discoverability.

6. Unrestricted File Uploads

One platform accepted file uploads without authentication or file type validation. Uploaded files were stored in web-accessible directories and executed by the application server. An attacker could upload executable code and achieve remote code execution without any credentials.

Combined with exposed configuration files and database access, this provided multiple independent paths to complete system compromise.

By the Numbers

  1. 0 valid credentials required to trigger most attack chains
  2. 40 verified customer records extracted in a single testing session
  3. 100 percent data density on sequential ID enumeration
  4. 1.2 million records theoretically accessible across one platform
  5. 1,203,500 loan application records confirmed accessible without authentication
  6. 15,284 member profiles with financial data exposed
  7. 42,355 user accounts with passwords stored in Base64 encoding
  8. 3,147 accounts sharing the identical password
  9. 3.5 days required to exfiltrate entire database at achievable request rates
  10. 16 open ports on origin infrastructure

Authorization and authentication are often conflated but represent separate concerns. Authentication verifies identity whereas authorization verifies permission. Systems frequently implement authentication correctly while omitting authorization entirely ,they verify the request comes from a valid user but assume valid users can access anything they request.

Server-side authorization checks are mandatory on every data request. Every endpoint must verify the authenticated user owns the resource being accessed.

Client-side secrets provide no protection. Minification and encoding are not security measures. Any secret reaching a browser is effectively public and should be declared compromised and rotated . Only server-side validation using secrets unknown to clients provides integrity protection.

Remediation Requirements

  • Authorization must be implemented server-side on every request. Clients cannot be trusted to enforce authorization. Every data endpoint must verify the authenticated user actually owns the resource before returning it.
  • Secrets must be removed from all client-side code immediately. Existing secrets must be rotated assuming compromise. New secrets must be fetched from backend-owned, session-scoped endpoints at runtime.
  • Database servers must never be internet-accessible. SQL Server port 1433, MySQL port 3306, and similar database ports should be restricted to internal network access only, accessed only through the application layer.
  • Firewalls must block all ports except those strictly required for operation. 80 and 443 are sufficient for web applications. SSH, FTP, SMB, WinRM, and other administrative ports must be restricted to specific administrative IP ranges and VPNs.
  • Source code repositories must be completely inaccessible from the internet. The .git directory, .env files, configuration files, and build artifacts should be outside webroot and protected by firewall rules.
  • Rate limiting must be implemented on all data endpoints, particularly those accepting enumerable parameters. Typical rates of 100 requests per minute per IP for most endpoints and 5-10 requests per minute for authentication endpoints are reasonable starting points.

What This Quarter Revealed

The six vulnerabilities we identified were not novel. OWASP documented Insecure Direct Object References (IDOR) in 2013. Client-side secrets have been a known failure mode for two decades. Sequential enumeration is a standard reconnaissance technique. Yet these vulnerabilities appear consistently across otherwise mature platforms because they reflect architectural decisions made during initial development and never questioned.

The barrier to exploitation is remarkably low. We required no specialized tools beyond curl and Python. The attack surface was navigable to anyone with basic HTTP knowledge and patience. In most cases, the entire database was accessible in hours.

The pattern across platforms is consistent: each failure mode appears independently, but successful attacks chain multiple failures together. Authorization bypass + leaked credentials + direct database access creates a complete compromise. Sequential enumeration + missing rate limits + multiple platforms creates mass exposure. No single remediation eliminates the threat—all must be addressed simultaneously.

For Teams Building Systems

If your platform handles financial transactions, identity data, or medical information, these patterns matter:

  • Implement authorization checks on every request. Verify ownership server-side, not client-side.
  • Assume any secret reaching a client is compromised. Rotate immediately and never embed credentials in code.
  • Never trust client-supplied identifiers to imply ownership of resources.
  • Restrict network access to only what's required. Close ports that aren't actively needed.
  • Design infrastructure assuming it will be discovered. Protect accordingly.

These aren't theoretical concerns. The vulnerabilities documented here are exploitable in production, and they have been exploited. Prevention requires treating security as a foundational architectural concern from day one, not as an addition layered on later.

This quarter's research confirmed that the most damaging vulnerabilities in financial and identity-handling systems are failures in foundational security principles: authorization, secret management, and infrastructure hardening. None require sophisticated attacks or specialized knowledge. All are preventable through disciplined implementation of established practices.

If you're building something that touches money, identity, or critical infrastructure, lock the doors before someone else does.