BSG Blog Berezha Security Group

Mobile App Security Testing: iOS and Android Pentest Guide

Your mobile app runs on devices you don’t control, in environments you can’t predict. That binary sitting on a user’s phone — with its local storage, hardcoded configuration, and network calls — is an entirely different attack surface from your web application. It demands a different testing approach.

Mobile malware — banking trojans and spyware in particular — remains a high-volume, persistent threat, and the apps most worth attacking are the ones moving money, health data, or identity. Meanwhile, regulatory pressure from PCI DSS 4.0, DORA, and HIPAA continues to push organisations toward mandatory mobile security assessments.

This guide covers what mobile app security testing involves, where iOS and Android apps typically fail, and how to decide between doing it yourself and hiring a professional pentester.

What is mobile app security testing?

Mobile app security testing is a structured evaluation of how your iOS or Android application handles data, authenticates users, communicates with backend services, and resists adversarial manipulation. It goes beyond web application testing because mobile apps introduce platform-specific risks: local data storage, inter-process communication, hardware sensor access, and the binary itself being available for reverse engineering.

A thorough mobile security assessment combines two approaches:

  • Static analysis examines the app binary, source code, and configuration files without running the application. It identifies hardcoded secrets, weak cryptographic implementations, insecure API endpoints, and misconfigurations in platform settings.
  • Dynamic analysis observes the running application to test authentication flows, intercept network traffic, manipulate runtime behaviour, and probe for business logic vulnerabilities that only appear during execution.

Neither approach alone is sufficient. Automated scanners catch the low-hanging fruit — hardcoded API keys, missing certificate pinning, known vulnerable libraries. But business logic flaws, authentication bypasses, and privilege escalation vulnerabilities require a skilled tester who understands your application’s context.

OWASP MASVS: the industry standard

The OWASP Mobile Application Security Verification Standard (MASVS) provides the definitive framework for mobile security testing. The current MASVS v2.x organises requirements into eight control groups that map directly to real-world attack patterns:

MASVS control groupWhat it coversWhy it matters
MASVS-STORAGEData at rest, keychain/keystore usage, logs, backupsLeaked data from device backups or logs is a top breach vector
MASVS-CRYPTOAlgorithm selection, key management, random number generationWeak crypto makes encrypted data functionally plaintext
MASVS-AUTHAuthentication and authorization, session management, biometrics, token handlingBroken auth leads directly to account takeover
MASVS-NETWORKTLS configuration, certificate pinning, API securityMan-in-the-middle attacks intercept credentials and data
MASVS-PLATFORMIPC, permissions, WebView security, deep linksPlatform misuse enables cross-app attacks and data leakage
MASVS-CODECode quality, build settings, dependency and supply-chain hygieneDebuggable builds and vulnerable dependencies hand attackers an easy start
MASVS-RESILIENCEReverse-engineering resistance, anti-tampering, anti-debuggingAn unprotected binary is an open invitation to attackers
MASVS-PRIVACYData collection, consent, tracking, PII handlingRegulatory non-compliance carries real financial penalties

MASVS v2.x dropped the older Level 1 / Level 2 verification tiers (retired in v2.0). Depth of verification is now expressed through the testing profiles in the companion MASTG: a baseline profile every app should meet, and a defence-in-depth / resilience profile for apps handling sensitive data such as financial transactions, health records, or authentication credentials. Most penetration testing engagements work to the baseline profile as a minimum and add the resilience profile for regulated industries.

MASVS defines what to verify; the OWASP Mobile Application Security Testing Guide (MASTG) defines how — concrete test cases that map each requirement to repeatable static and dynamic checks. The OWASP Mobile Top 10 (2024) sits alongside them as the risk taxonomy that frames findings for non-specialist stakeholders.

Mobile application penetration testing methodology: how an engagement works

Mobile app penetration testing follows a structured methodology rather than ad-hoc poking. A disciplined engagement moves through the same phases regardless of platform, each mapping to the MASVS control groups and MASTG test cases above. Here is how a professional mobile application penetration testing engagement actually runs.

1. Scoping and access

The engagement starts by defining what gets tested and how. We identify the platforms (iOS, Android, or both), the in-scope user roles, the backend APIs the app talks to, and any third-party integrations. We also agree on a testing approach. Most mobile app pentests run grey-box: the tester gets a build, valid test credentials for each role, and a basic architecture overview, but works without source code. That mirrors what a motivated attacker can achieve after downloading the app and reverse-engineering it, while skipping the wasted days of blind reconnaissance. White-box adds source and lets the tester reach deeper coverage in the same window; black-box withholds everything and best simulates an external attacker with no prior knowledge. Which one fits depends on your goals and budget — our breakdown of black-box vs white-box vs grey-box testing walks through the trade-offs.

Scoping also locks down the rules of engagement: which backend environment to hit (a staging API that mirrors production is ideal — testing live payment flows needs explicit sign-off), test accounts that can be reset, and any rate limits or fraud controls that might lock the tester out mid-engagement.

2. Test-environment setup

Before any testing happens, the tester builds a controlled environment where the app’s defences can be observed and manipulated. That means a rooted Android device or jailbroken iOS device (or carefully configured emulators and simulators), an intercepting proxy with its CA certificate trusted by the app, and runtime instrumentation tooling staged. Certificate pinning and root/jailbreak detection are frequently the first obstacles, and bypassing them is a prerequisite for seeing the traffic at all. We cover the mechanics of this setup in detail below.

3. Static analysis

With the environment ready, testing begins with the binary at rest. The tester decompiles the Android APK (jadx, apktool) or analyses the iOS IPA, and reviews the manifest, entitlements, embedded configuration, and strings. This phase surfaces hardcoded secrets and API keys, insecure storage flags, exported components, debuggable builds, weak cryptographic choices, and outdated third-party libraries with known CVEs. Static analysis is fast and catches a meaningful share of findings, but it only describes what the code could do — confirming exploitability is the job of the next phases.

4. Dynamic and runtime testing

Now the app runs on the instrumented device and the tester observes its live behaviour. This is where most high-severity findings emerge. Using Frida and objection, the tester hooks functions, inspects and modifies arguments and return values, dumps in-memory secrets, and tampers with the running app. Local storage is inspected after realistic usage to catch tokens written to SharedPreferences, UserDefaults, caches, or logs. Network traffic flows through the proxy so every request and response can be read and replayed. Client-side controls — biometric gates, feature flags, jailbreak detection — are tested by trying to defeat them at runtime, because anything enforced only on the device is enforced only until an attacker patches it.

5. Backend API testing

The app’s traffic exposes the backend APIs, and that is where the real attack surface usually lives. The tester replays and manipulates captured requests to probe authentication, session handling, authorization, and business logic on the server. A mobile client is only as secure as the API behind it — this phase is substantial enough that it gets its own section below.

6. Exploitation and business-logic testing

Individual findings are then chained into realistic attacks. Can a low-privilege user reach another user’s data by swapping an identifier? Can the purchase or subscription flow be manipulated to unlock paid features for free? Can a tampered build defeat anti-fraud or licensing checks? This is the work automated scanners cannot do: reasoning about your application’s specific logic, combining several medium-severity issues into one high-severity attack path, and demonstrating concrete business impact rather than a list of theoretical weaknesses.

7. Reporting, remediation, and free retest

The engagement ends with a report that ranks each finding by severity and business impact, explains how it was exploited with reproduction steps, and gives platform-specific remediation guidance your developers can act on. A debrief call walks the engineering team through the highest-risk issues. After fixes ship, a free retest verifies the remediation actually closed the gaps — and gives you clean evidence to hand to auditors, customers, or an app store review. If a quote omits the retest, treat that as a red flag.

Mobile API penetration testing: the backend behind every app

Mobile API security testing is where most serious findings come from. A mobile app is mostly a thin client — the interesting logic (accounts, payments, entitlements, personal data) lives behind the backend APIs the app calls, and that server-side surface is usually larger and more valuable than the binary itself. You can harden the client perfectly and still be wide open if the API trusts whatever the app sends. This is why mobile API penetration testing is not an optional add-on to a mobile assessment; it is often where the highest-severity issues surface, and it answers the kind of “API and mobile” testing buyers are looking for.

What a mobile-focused API security testing effort covers:

  • Authentication and session management — how tokens are issued, scoped, refreshed, and revoked. Long-lived tokens that never rotate, refresh tokens that survive logout, and JWTs the server fails to validate are routine findings. The tester confirms that a stolen or replayed token cannot be used indefinitely.
  • Broken object-level authorization (BOLA/IDOR) — the single most common and most damaging API flaw. The tester swaps object identifiers (/users/123/orders/users/124/orders) to see whether the server enforces ownership or simply trusts the ID the client sent. Mobile apps make this especially tempting to get wrong, because developers assume the app’s UI is the only thing calling the API.
  • Broken function-level authorization — whether a standard user can invoke admin-only or privileged endpoints that the app simply hides from their UI. Hiding a button is not access control.
  • Rate limiting and resource controls — whether login, OTP, password-reset, and payment endpoints throttle abuse. Missing rate limits enable credential stuffing, OTP brute-forcing, and enumeration attacks that a mobile client would never trigger but a script trivially does.
  • Mobile-specific API risks — endpoints that trust client-supplied values they should compute server-side (price, user role, device-attestation status), undocumented or legacy API versions still reachable by older app builds, and excessive data exposure where the API returns far more fields than the app displays, leaking PII to anyone reading the traffic.

Because the tester already has the app’s traffic captured during the dynamic phase, this work flows naturally out of runtime testing — the same proxy session that exposed an insecure local cache becomes the launchpad for attacking the API that fed it.

Where iOS and Android apps typically fail

Across our application security assessments, certain vulnerability patterns appear consistently across both platforms. Here are the findings we see most often.

Data storage vulnerabilities

The problem: Apps store sensitive data in locations accessible to other apps, device backups, or forensic analysis.

On Android, common mistakes include writing tokens or credentials to SharedPreferences in plaintext, logging sensitive data to Logcat, and failing to exclude files from automated backups. On iOS, storing secrets in UserDefaults instead of the Keychain, caching sensitive responses in URLCache, and leaving debug data in the app’s sandbox are frequent findings.

What to do: Use the platform’s secure storage — Android Keystore and iOS Keychain — for all secrets, tokens, and credentials. Disable automated backups for sensitive data directories. Strip all debug logging from release builds.

Insecure network communication

The problem: Apps transmit sensitive data over insecure channels or fail to verify server identity.

The most common finding is missing or improperly implemented certificate pinning. Without it, an attacker on the same network (think public Wi-Fi, compromised corporate network) can intercept all API traffic using a proxy with a self-signed certificate. Android’s Network Security Config and iOS’s App Transport Security (ATS) provide baseline protections, but many apps weaken these defaults for development convenience and ship those weakened configurations to production.

What to do: Pin the server’s public key (SPKI), or an intermediate CA, rather than the leaf certificate — leaf pinning breaks on routine certificate rotation. Use Android’s Network Security Config to enforce TLS and define pin sets. On iOS, ensure ATS is enabled without exceptions. Never ship debug proxy configurations.

Authentication and session management

The problem: Apps implement authentication logic on the client side, making it trivially bypassable.

Client-side biometric checks that don’t tie to server-side session validation are common in fintech apps. We frequently see apps where disabling a biometric prompt — through runtime manipulation or binary patching — grants full access. Token storage and refresh logic also appear frequently: long-lived tokens without rotation, refresh tokens stored alongside access tokens, and missing token revocation on logout.

What to do: Treat the client as untrusted. All authentication decisions must be validated server-side. Use short-lived access tokens with secure refresh flows. Bind biometric authentication to a hardware-backed cryptographic key whose use requires a successful biometric check — the iOS Secure Enclave / Keychain access control, or the Android hardware-backed Keystore (StrongBox where available) — not a client-side boolean.

Hardcoded secrets and API keys

The problem: Developers embed API keys, encryption keys, or credentials directly in the application binary.

Because mobile app binaries are distributed to end users, anything in the binary is extractable. Decompiling an Android APK with jadx or disassembling an iOS binary with Hopper takes minutes. We routinely find AWS keys, Firebase secrets, third-party API tokens, and sometimes database credentials hardcoded in mobile apps.

What to do: Never embed secrets in mobile app binaries. Use server-side proxying for third-party API calls. If a client-side key is unavoidable (such as a Google Maps API key), restrict it by bundle ID, API scope, and usage quota.

Platform-specific misconfigurations

Android-specific findings:

  • Exported Activities, Services, and Broadcast Receivers that accept untrusted input
  • Insecure content providers exposing internal databases
  • WebView with JavaScript enabled and access to local files
  • Debuggable flag left enabled in release builds
  • Permissive intent filters that allow deep link hijacking

iOS-specific findings:

  • Custom URL schemes vulnerable to hijacking (Universal Links are safer)
  • Pasteboard data accessible to other apps
  • Improper handling of background screenshots (sensitive data visible in app switcher)
  • Keychain items with overly permissive access groups
  • Missing jailbreak detection for high-security apps

Tools for mobile app security testing

Static analysis

ToolPlatformUse case
MobSFBothAutomated static + dynamic analysis, great starting point
jadxAndroidDecompiles APK to readable Java source
apktoolAndroidDecodes resources, enables binary inspection
Hopper / GhidraBoth (native code)Disassembly of iOS Mach-O binaries and Android native libraries
SemgrepBothCustom rules for source code security patterns

Dynamic analysis

ToolPlatformUse case
FridaBothRuntime instrumentation — bypass pinning, hook functions, modify behaviour
Burp Suite / OWASP ZAPBothHTTP(S) traffic interception and manipulation
objectionBothRuntime exploration built on Frida
DrozerAndroidIPC testing — exported components, content providers
Frida / LLDBiOSRuntime manipulation and debugging (Cycript is now legacy)

Getting started

MobSF is the best entry point for teams new to mobile security testing. It performs automated static and dynamic analysis and generates reports that highlight the most critical findings. But remember: automated tools surface only a fraction of what a skilled manual tester finds. They excel at configuration issues and known patterns; they miss business logic flaws entirely.

Setting up the test environment: iOS vs Android

Knowing the tools is one thing; assembling them into a working test rig is where most do-it-yourself mobile app security testing stalls. The platform’s own defences are designed to stop exactly the kind of inspection a tester needs to perform, so the environment has to be built deliberately — and the setup differs meaningfully between iOS and Android.

Rooted Android and jailbroken iOS. Effective dynamic testing usually needs elevated access to the device. On Android that means a rooted device (or a rooted emulator image) so the tester can read app-private storage, inject instrumentation, and trust a custom CA. On iOS it means a jailbroken device, which is harder to obtain because jailbreaks lag behind current iOS versions — teams often keep a dedicated older test handset for this reason. Without elevated access, you can still test traffic and observe behaviour, but you lose the ability to inspect on-device storage and hook the app at runtime.

Real device vs emulator vs simulator. The right choice depends on the test:

  • Android emulators are excellent for most work — fast to provision, easy to snapshot and reset. Rooting depends on the image: AOSP/Google-APIs images are trivially rooted (adb root), while Google Play images behave like retail devices and resist rooting. Neither emulator passes hardware-backed Play Integrity or attestation, so an app gated on StrongBox keystore, hardware attestation, NFC, or biometrics still needs a real device.
  • iOS simulators run an x86/ARM build of the app and do not behave like a real device for security purposes: no Keychain hardware backing, no jailbreak surface, no real network stack. They are useful for quick functional checks but not for a genuine assessment.
  • Real devices are mandatory whenever the app relies on hardware-backed keys (the iOS Secure Enclave or Android StrongBox/TEE-backed Keystore), biometrics, or push/attestation — which covers most fintech and healthcare apps. A serious mobile assessment almost always uses at least one real device per platform.

Frida and objection for runtime instrumentation. Frida is the workhorse. It injects a JavaScript engine into the running process so the tester can hook any method, read and rewrite arguments and return values, and dump objects from memory. objection sits on top of Frida and packages the common tasks — listing Keychain items, dumping the iOS keychain, bypassing pinning, exploring the Android heap — behind ready-made commands, which makes the early triage far faster.

Certificate-pinning bypass. Most well-built apps pin their server certificate, so the moment you point them at an intercepting proxy they refuse to connect and you see nothing. Bypassing the pin is therefore a prerequisite for almost all network and API testing, not an exploit in itself. The standard approach hooks the platform’s TLS validation routines (or the specific pinning library, such as OkHttp’s CertificatePinner or TrustKit) with Frida or an objection one-liner, so the app accepts the proxy’s certificate. If the pin cannot be bypassed at runtime, that itself is a finding worth noting — but in practice client-side pinning is consistently defeatable, which is exactly why the server must never trust the client.

Root and jailbreak detection bypass. High-security apps often refuse to run on a rooted or jailbroken device. Because that check executes on the device the attacker controls, it is bypassable — typically by hooking the detection functions with Frida or objection so they always report a clean device. Demonstrating the bypass matters: it shows the client cannot enforce trust, and it reinforces that every security decision has to be validated server-side. A tester who cannot get past root/jailbreak detection simply cannot assess the rest of the app, so this is one of the first hurdles cleared in any engagement.

When to hire a professional

Automated tools and internal testing can handle baseline security hygiene. But certain scenarios demand a professional mobile application penetration testing engagement and the application security expertise behind it:

  • Regulatory requirements — PCI DSS, HIPAA, SOC 2, and DORA audits often require third-party penetration testing reports from qualified assessors.
  • High-value targets — Fintech, healthcare, and apps handling payment data face motivated, skilled attackers. The testing needs to match the threat.
  • Pre-launch assurance — A professional pentest before your app hits the App Store or Google Play catches vulnerabilities that would be expensive to fix post-release.
  • After a breach or incident — Independent assessment provides objective findings and credible remediation evidence for regulators and customers.
  • Complex architectures — Apps with multiple backend integrations, custom authentication, or real-time communication protocols need testers who’ve seen these patterns before.

A professional mobile app pentest typically costs $8,000–$25,000 per platform — see our penetration testing cost breakdown for ranges across every test type — takes 2–3 weeks, and should include a detailed findings report with remediation guidance and a free retest to verify fixes. If your quote doesn’t include retesting, ask why.

Building mobile security into development

Testing at the end of the development cycle is better than not testing at all, but shifting security left is more effective and cheaper. Here’s a practical approach:

  1. Threat model during design — Before writing code, identify what data your app handles, where it flows, and what an attacker could gain. Focus testing resources on the highest-risk areas.

  2. Use platform security features — Android Keystore, iOS Keychain, Network Security Config, ATS. These exist because the platform vendors have already solved common security problems. Use them.

  3. Automate what you can — Run MobSF or Semgrep in CI/CD to catch regressions. Flag new uses of insecure APIs, hardcoded strings, and missing security configurations.

  4. Train your developers — Mobile developers who understand OWASP MASVS write more secure code from the start. Targeted secure coding training for mobile platforms reduces the volume and severity of findings in every subsequent pentest.

  5. Test before every major release — New features mean new attack surface. Schedule professional pentesting before major releases, and use automated tools for interim builds.

Frequently asked questions

What’s the difference between mobile app testing and web app testing?

Mobile app testing covers the binary on the user’s device — local storage, platform APIs, hardware access, reverse engineering — plus the backend APIs. Web app testing covers the browser-delivered client (DOM, client-side scripts and storage) plus the server-side application and its APIs, but there is no installed binary and no OS-level platform, IPC, or hardware attack surface. A mobile app with a web API backend needs both types of testing for complete coverage.

How long does a mobile app pentest take?

Most mobile app penetration tests take 2–3 weeks per platform. Simple apps (few features, standard authentication) can be tested in 1–2 weeks. Complex apps with custom protocols, multiple user roles, and offline functionality may require 3–4 weeks. Testing both iOS and Android versions in parallel saves time but requires separate testing for each platform’s unique attack surface.

Do I need to test both iOS and Android separately?

Yes. Even if both apps share a common codebase (React Native, Flutter, Kotlin Multiplatform), the compiled binaries interact differently with each platform’s security features. Android’s content providers, broadcast receivers, and intent system create attack surface that doesn’t exist on iOS. iOS has its own unique risks with keychain configuration, URL scheme handling, and pasteboard behaviour. Testing one platform doesn’t cover the other.

Can automated scanners replace manual pentesting?

Automated scanners are useful for baseline checks — they’ll catch hardcoded secrets, missing certificate pinning, and known vulnerable libraries. But they can’t test business logic, evaluate authentication flows in context, or chain vulnerabilities together the way a skilled tester does. That gap is exactly where the high-severity findings live. Use both: scanners for continuous monitoring, manual pentesting for depth.

Shipping an iOS or Android app that handles money, health, or identity?
BSG's appsec team tests both platforms against the current OWASP MASVS (v2.x) and MASTG — Frida, certificate-pinning bypass, runtime tampering, the works — with a detailed report and a free retest within 90 days.

Request a quote →