API pentesting and the BRB Pix case: 520 transfers
BRB lost R$53.1M across 520 unauthorized Pix transfers and the cause is disputed. What it shows about per-window caps and anomaly detection.
The BRBJUS system, which BRB operates for the Bahia State Court of Justice, lost R$53.1 million across 520 unauthorized Pix transfers. The cause is disputed and the case is before Brazil’s Supreme Court. My thesis is not about the cause. It is this: whatever the origin was, a payment API with no per-window cap and no anomaly detection let an unauthorized access turn into 520 operations in four hours.
What you get out of this: why “strong passwords” is not API security, and what to demand in the scope of your next test so your team does not find out through the press.
What happened
Reporting from Bastidor, carried by Convergência Digital, the operations began around 6:10am on September 17. The bank confirmed the anomalies at 10am and blocked the system at 10:10am, four hours after the first transfer. The first estimate pointed to R$43 million, a figure that rose to R$53.1 million. The bank triggered the Pix reversal mechanism, notified the central bank and committed to restore the full amount to the judicial accounts.
On the origin, there are two versions and they do not agree.
The court sent an official letter on September 19 stating that the incident happened in infrastructure owned by BRB. The bank presented a different version: in a letter dated September 22, it said the origin of the problem was external to the environment it manages. According to the report, the bank blames an external digital certificate for the diversion of funds. In a document dated September 21, BRB had described linking the digital certificate to the individual’s CPF as a proposal. The District Federal Attorney General’s office joined the documents to the case before the Supreme Court, and the court opened an administrative investigation on September 25.
Nobody yet knows whether this was a compromised certificate, an integration failure or something else. That is what the investigation is for. What the source lets us state without risk is the effect: 520 transfers, a four-hour window, no apparent lock.
The court has since restored the system with operating limits: R$1 million in the daytime period starting at 7am, and R$100 thousand overnight starting at 6pm. The institution described the measure as preventive and temporary, intended to reinforce the security, monitoring and traceability of operations.
Two numbers deserve attention. The first is that the initial estimate came in more than R$10 million below the final figure, which shows the size of the error when you measure damage by sampling. The second is that the block happened four hours after the operations began.
Why this is not a “weak password” story
There is a class of failure that never shows up in a vulnerability scan report. It happens when authentication works, the user is properly identified, and they can still do something they should not be able to do.
Consider the endpoint that receives a transfer. It validates: is the user authenticated? Yes. Does the account exist? Yes. Is the amount within the balance? Yes. What it does not validate is the one thing it should validate first: how many times that account can be debited inside a ten-minute window, and whether that destination already appeared in the other 519 transfers.
No automated vulnerability tool finds that. It looks for known code patterns. Here the code is fine. The business rule simply does not exist.
And that is what this case shows, whatever the origin turns out to be. A compromised certificate, an integration bug, a process failure: any one of them becomes a bounded loss once there is a cap per transaction and anomaly detection by volume and by destination. Without them, the loss scales until the whole system wakes up.
If I were that company’s CTO, the first thing I would ask for tomorrow is not an infrastructure pentest. It is a review of the business rules in the transfer API: a cap per transaction, a cap aggregated across a time window, anomaly detection, idempotency, and the audit trail showing who requested what.
What to demand in your next pentest scope
Most scopes I read test authentication exhaustively and treat the API as an appendix to the system. That is comfortable and it does not find the thing that steals money.
Three things change the outcome.
First, business logic named in the scope, in writing. Without the rules on the page, the test runs the OWASP API Top 10 and hands you a polished report that never answers whether someone can withdraw twenty times in a minute.
Second, a test of the per-destination cap. If your API accepts the same amount to the same account a thousand times in an hour and you have no rule against it, that is a finding, not a discussion.
Third, a report that states what was not tested. A report that only lists what was found hides the bigger hole, which is the part nobody asked anyone to look at.
What to do now
- Ask for the API test scope to list the business rules to be verified, not just OWASP.
- Test per-transaction caps and window-aggregated caps on any API that moves money.
- Verify that anomaly detection exists for volume and destination, and how long an alert takes to reach a human.
- Require a report covering what was not tested, plus a retest after remediation.
- Treat the BRB case for what it is: a process that noticed four hours after the operations began. The gap between the first estimate and the final figure was more than R$10 million.
Tomorrow someone will ask why the bank did not flag it earlier. The answer is always the same, and it does not change from company to company. Nobody had built the detector before the incident needed one.