Stabilizing a legacy banking app and rebuilding customer trust
Engineering

Stabilizing a legacy banking app and rebuilding customer trust
A retail bank's mobile app was crashing, hard to change and being exploited by fraudsters. We stabilized it, closed the security gaps that were costing customers money, and helped turn its app-store reputation around, all without a rewrite.
The challenge
When we joined the engagement, the app was unstable, with frequent crashes. The codebase carried roughly ten years of legacy: Java 8, with some modules on Java 11, organized as modular projects inside a larger application. It took one to two months just to understand where changes needed to be made, while the client needed to see progress within the first few weeks.
Beyond stability, there was a trust problem. Customers were losing money through social engineering, often by being tricked into sharing one-time passwords, and the bank was taking roughly five calls a month from customers about money leaving accounts through the app. Customers could also have the same account active on multiple phones, which opened the door to account takeover.
What we did
Our first goal was to stabilize, then build. A typical example: customers couldn't reliably change their PIN. The app had many user states, and an old PIN was being cached, so the system sometimes used the old PIN instead of the new one. We worked through the state handling to fix it.
The security work is where the technical and business stories meet. We introduced device-based controls:
One account, one phone. An account can only be registered on one device. If someone tries to register it on another phone, the change in device fingerprint lets us stop an unauthorized takeover.
An extra verification step. Fraudsters had been entering random mobile numbers to reach the next screen and then calling the customer. Requiring the account number as well closed that route.
Automatic blocking. When a single device tries many different phone numbers, we block it. It can no longer register on the app unless the bank releases it.
The controls worked. Once they were in place, the team was blocking between 100 and 200 suspicious devices a day, each one a fraud attempt stopped before it reached a customer. The bank's financial crime team, who had been fighting these attacks, went from cautiously trialing the controls to relying on them.
We were deliberate about not rewriting the architecture. We worked within the existing patterns, ran a static application security scan, and updated the libraries it flagged. Delivery ran on a simple operating model: daily internal and client stand-ups, and a single ticketing board as the one channel for requirements.
The outcome
Over the past year, the app-store rating rose from 2.6 to 4.5 on both apps, with far more five-star ratings than before.
Trust grew alongside it. When a government-mandated levy came in, the bank was one of the first to ship it on the mobile app, within about a week of the central-bank directive. That track record led the bank to trust us with more, including integrations with other financial services such as pension schemes and card blocking and unblocking.
On a legacy system under pressure, the answer is often not a rewrite. Stabilize the core, close the specific gaps that are eroding customer trust, deliver reliably on short timelines, and the relationship, and the scope, tends to grow from there.
Facing a similar challenge? Get in touch. We'd be glad to talk it through.



