Hi everyone!
We are back with another interesting write-up. This time, We will share how we found an easy Account Takeover (ATO) vulnerability in an Android application during a penetration test. The app we tested was for healthcare, mainly used for patient engagement and support. For privacy reasons, let’s call the app test.apk.
OTP stands for One-Time Password. It’s a temporary code sent to your phone or email to confirm your identity during login or signup. Instead of using just a regular password, apps use OTPs to add another layer of security. Each OTP is valid only for a short time and can be used only once, which helps protect against unauthorized acces even if someone knows your password.
The app (test.apk) helps patients connect with healthcare services. To protect user data, the app had a proper authentication process with several steps, such as verifying personal information, OTP code, and PIN code. But I found a serious bug in the OTP validation process that allowed me to bypass authentication and take over accounts.Let’s look at how the login flow works.
Here’s how a user logs in to the app:
1.Personal Info Step
The user enters:
2. Verification Step
The app checks the data and then displays:
i. Partially hidden phone number (like ******1234
)
ii. Partially hidden email (like t****@****.com
)
3. OTP Step
The user selects either phone or email to receive the OTP (One-Time Password).
4. PIN Step
After entering a valid OTP, the app asks for a PIN code to create a new PIN code (Normally on Mobile devices for app lock).
The main issue was with the OTP verification API.
When the user enters an OTP, the app sends it to the server and gets a response in JSON format like this:
{
"stat": 0
}
"stat": 0
means the OTP is invalid"stat": 1
means the OTP is validNow here’s the problem:
This check was only done on the client side not properly verified on the backend.
So we tried response manipulation.
We opened the app and entered: First Name, Last Name and DOB
We chose any email to receive an OTP.
Then, we entered a fake/invalid OTP like 111111
.
Using Burp Suite, I intercepted the response from the server. It returned:
{
"stat": 0
}
I changed stat: 0
to stat: 1
in the response and forwarded it:
{
"stat": 1
}
And boom we were allowed to move to the next step without entering the real OTP.
The app then asked me to set a new PIN. We did that and successfully logged in.
We bypassed the OTP step completely using response tampering. This allowed us to take over an account!
This vulnerability could allow Account Takeover (ATO). But there’s a small limitation:
To reach the OTP screen, the attacker must first know the victim’s:
These details can be hard to guess, especially the DOB, which reduces the risk slightly.
But still, if the attacker somehow knows this information (like in a hospital setting or insider threat), they can:
That’s a serious issue in healthcare apps, where sensitive personal and medical data is involved.
An attacker can:
Healthcare data is one of the most sensitive types of personal information. It includes your medical history, test results, prescriptions, mental health records, and even personal details like your home address and contact information. If this information falls into the wrong hands, it can lead to:
In short, keeping healthcare data confidential isn’t just a technical matter but also it cause serious psychological effects.
In conclusion, this OTP bypass vulnerability in the Android app shows how a small flaw in the authentication flow can lead to full account takeover. It highlights the importance of properly validating OTPs on the server side. If you have any questions or want to connect, feel free to reach out on LinkedIn or X.