Follow the state machine in source
With white-box access, we traced the loan application’s status field through every service and found it could be set directly by the client in one legacy route.
Penspy is an independent security firm, testing web applications and auditing against the frameworks you answer to.
Every individual step in the loan workflow was secure. The order of the steps was not.
Representative engagement. Client names, figures and identifying details are changed or combined; no client findings are published in identifiable form.
A consumer lending fintech.
The lender ran affordability checks, identity verification and a manual underwriting step before releasing funds to a card. Each service had been tested on its own.
Nobody had tested what happened between them.
With white-box access, we traced the loan application’s status field through every service and found it could be set directly by the client in one legacy route.
The disbursement endpoint checked “already paid” before writing “paid”. Twenty parallel requests produced three disbursements.
Both findings scored critical under CVSS v4.0 once the environmental metrics reflected that real money moved, not just data.
| Severity | Finding | Maps to | Status at retest |
|---|---|---|---|
| Critical | Application status writable from the client on a legacy update route, skipping underwriting. | WSTG-BUSL-06 · ASVS V2 | Closed |
| Critical | Race condition on disbursement allowed duplicate payouts. | WSTG-BUSL-04 · CWE-362 | Closed |
| High | Interest calculated in floating point; rounding drift on early repayment. | ASVS V2 · CWE-681 | Closed |
| High | Identity-verification webhook accepted unsigned callbacks. | API10:2023 · ASVS V4 | Closed |
| Medium | Verbose error responses exposing internal service names. | A10:2025 · ASVS V16 | Closed |
What changed.
Status transitions now go through a single server-side state machine, and disbursement uses an idempotency key with an atomic update. Both criticals were verified closed with the same parallel test that found them.
The client added the race-condition test to its own CI pipeline, so the regression cannot quietly return.
Tell us what you ship and who is asking for proof. We will come back with a scope and a range.