Skip to content
Engineering deep-divesAll articles

Mobile App Security: OWASP MASVS Checklist & Best Practices

A mobile app runs on an untrusted device you do not control. Here is the engineering guide and OWASP MASVS v2.1 mobile application security checklist we use to secure storage, OAuth 2.0 PKCE, TLS pinning, and hardware attestation on iOS and Android.

Artem Zaitsev
Artem ZaitsevCTO · Idealogic
Author: Artem ZaitsevPublished: Updated: Reading time: 19 minHow we write →
On this page
Idealogic: mobile app security layers and checklist

Mobile app security is the engineering discipline of protecting user data, authentication tokens, cryptographic keys, and backend APIs when your software executes on hardware you do not own or control. When teams ask for a practical mobile application security checklist, the first mindset shift we enforce at Idealogic is abandoning web-server assumptions: an iOS IPA or Android APK lives in a stranger's pocket, where any determined attacker can pull the binary off the phone, decompile it in thirty seconds, attach a runtime debugger, and inspect every file written to disk.

Building a resilient iOS or Android product does not require inventing proprietary cryptography or degrading your user experience. It requires applying defense in depth across the client binary, the operating system hardware security module, the transport layer, and the API gateway. Below is the architecture guide and OWASP MASVS v2.1 checklist our engineering teams run before shipping consumer, enterprise, fintech, and healthtech mobile applications.

The short version

  • Assume the client device is compromised: An attacker can decompile your APK with jadx, inspect your iOS binary with Ghidra, and hook methods at runtime with Frida. Never ship a secret in the client binary that would compromise other users if extracted.
  • Anchor secrets in silicon, not plain files: Store tokens and cryptographic keys inside the iOS Keychain (kSecAttrAccessibleWhenUnlockedThisDeviceOnly backed by the Secure Enclave) and the Android Keystore System (backed by StrongBox hardware where supported), never in NSUserDefaults, SharedPreferences, or plain AsyncStorage.
  • Bind biometrics to cryptography, not booleans: A true/false biometric callback can be bypassed by a one-line Frida script on a rooted device. Always require the biometric sensor to unlock a hardware-bound cryptographic key via SecAccessControl or BiometricPrompt.CryptoObject.
  • Use OAuth 2.0 with PKCE and FIDO2 Passkeys: Public mobile clients cannot keep a client_secret confidential. Enforce Proof Key for Code Exchange (RFC 7636) on every OAuth flow and adopt FIDO2 Passkeys to eliminate SMS OTP phishing.
  • Pin SPKI public-key hashes with backup pins: Enforce TLS 1.3 everywhere. When adding pinning for high-risk apps, pin the SHA-256 hash of the Subject Public Key Info (SPKI) along with an off-CA backup key so certificate rotation never bricks your install base.
  • Verify client integrity at the API boundary: Treat the backend API as the true security perimeter. Enforce object-level authorization on every request and verify hardware attestation tokens from Apple App Attest and the Google Play Integrity API.

Why mobile app security differs fundamentally from web security

Teams transitioning from backend or web work routinely misjudge the mobile threat model. On the web, your backend code executes inside a cloud VPC you control, your environment variables stay on your server, and the browser interacts only through remote HTTP requests.

In mobile app development, you package your compiled code, assets, native libraries, and configuration files into a signed archive (.ipa for iOS, .aab or .apk for Android) and hand it directly to the outside world. Once that archive lands on a physical device or an emulator, the attacker has physical and administrative root access to the execution environment.

During security audits at Idealogic, our first pass on a release build takes less than two minutes:

  1. Pull the installed APK off a test Android device using adb shell pm path and adb pull.
  2. Decompile DEX bytecode and resources with jadx-gui, or unpack an iOS .ipa payload to inspect Mach-O binaries and React Native Hermes bundles.
  3. Run strings, ripgrep, and entropy scanners across resources.arsc, Info.plist, BuildConfig.java, assets, and native .so libraries.
  4. Launch the app on a rooted device running frida-server and mitmproxy to inspect every SQLite write, Keychain read, and HTTPS payload in real time.

If a team placed an AWS secret, a Stripe secret key, or an admin API token inside a .env file compiled into the binary, jadx or a memory dump exposes it immediately. Worse, an attacker does not need your UI to talk to your backend; once they inspect your network calls, they can replay modified requests directly from a script.

That reality dictates the core rule of mobile security architecture: client-side controls protect a single user's local data when their phone is lost, stolen, or infected, while server-side controls protect your platform and every other user from a hostile client.

Five layers, each assuming the one above it could fail: the device is untrusted, so the backend stays the real boundary

The OWASP Mobile Top 10 (2024) mapped to engineering controls

The OWASP Mobile Top 10 (2024 release) catalogues the vulnerability classes that cause breaches in production iOS and Android software. Below we map every category directly to the architectural mistake that causes it and the engineering control that prevents it.

OWASP 2024 RiskWhat We See Broken in AuditsProduction Engineering Control
M1: Improper Credential UsageAPI keys hardcoded in BuildConfig, Info.plist, .env files, or native C++ stringsMove third-party secrets behind a backend proxy; issue short-lived tokens via OAuth 2.0 PKCE
M2: Inadequate Supply Chain SecurityOutdated CocoaPods, Swift packages, Gradle dependencies, or unverified third-party SDKsGenerate CycloneDX SBOMs in CI, pin dependency hashes in lockfiles, and audit SDK network access
M3: Insecure Authentication & AuthorizationClient-side role checks, boolean biometric callbacks, or missing BOLA/IDOR checks on API endpointsEnforce object-level authorization server-side on every request; bind biometrics to Keychain/Keystore crypto objects
M4: Insufficient Input/Output ValidationUnvalidated deep links (intent:// or custom URL schemes) opening arbitrary WebView URLs with JS bridgesValidate deep link hosts and parameters; restrict WebView navigation to allowlisted HTTPS origins
M5: Insecure CommunicationCleartext HTTP fallbacks in AndroidManifest.xml, or custom TrustManager ignoring cert errorsEnforce TLS 1.3 via NSAppTransportSecurity and network_security_config.xml; fail closed on cert errors
M6: Inadequate Privacy ControlsLogging PII or bearer tokens to NSLog, Logcat, Crashlytics breadcrumbs, or session replay toolsRedact sensitive fields in structured loggers, mask UI inputs during screen recording, and minimize data collection
M7: Insufficient Binary ProtectionsUnobfuscated release APKs with debug symbols intact and zero runtime integrity verificationEnable R8 full mode on Android and symbol stripping on iOS; validate integrity with App Attest and Play Integrity API
M8: Security Misconfigurationandroid:debuggable="true" or android:allowBackup="true" left in release manifests; exported componentsHarden manifests via automated CI lint rules; disable automatic cloud backup of sensitive app directories
M9: Insecure Data StorageJWTs or sensitive records stored in SharedPreferences, NSUserDefaults, AsyncStorage, or plain SQLiteStore keys in iOS Secure Enclave Keychain or Android StrongBox Keystore; encrypt local databases with SQLCipher
M10: Insufficient CryptographyDeprecated algorithms (MD5, SHA-1, DES, AES-ECB), static IVs, or keys derived from device IDsUse AES-256-GCM or ChaCha20-Poly1305 with hardware-generated random keys managed by platform crypto APIs

Notice how M1 (Improper Credential Usage) rose to the number-one spot in the 2024 OWASP update. With the rapid adoption of third-party AI, mapping, and payment APIs, teams under deadline pressure frequently drop an API key into a client configuration file, assuming that compiling the app hides the string. Any key that bills your account or accesses cross-user data must live on your backend server, never inside the mobile client.

The four hardware and protocol pillars that enforce OWASP MASVS v2.1 in production

Layer 1: Hardware-backed data storage and cryptography (MASVS-STORAGE & MASVS-CRYPTO)

The most common high-severity finding in mobile penetration tests is sensitive data sitting in plaintext inside the application sandbox. While the OS sandbox prevents other non-privileged apps from reading your files during normal operation, it does not protect data when a backup is extracted via Finder or adb backup, when a lost phone is rooted or jailbroken, or when the OS captures an unmasked screenshot for the multitasking switcher right as the user backgrounds a sensitive screen.

Securing credentials on iOS: Keychain Services and the Secure Enclave

On iOS app development builds written in Swift, UserDefaults (NSUserDefaults) writes an unencrypted .plist file inside the app container. Never store session tokens, refresh tokens, PIN hashes, or PII in UserDefaults.

Instead, store credentials in Apple Keychain Services and configure accessibility and access control flags explicitly:

  • Accessibility class: Set kSecAttrAccessibleWhenUnlockedThisDeviceOnly (or kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly only if a background worker strictly requires token access while locked). The ThisDeviceOnly suffix prevents the Keychain item from migrating to an attacker-controlled device when a backup is restored.
  • Secure Enclave key generation: Create an elliptic curve P-256 key (kSecAttrKeyTypeECSECPrimeRandom, 256-bit) with kSecAttrTokenIDSecureEnclave, combined with SecAccessControlCreateWithFlags using .privateKeyUsage and .biometryCurrentSet. Using .biometryCurrentSet (rather than .biometryAny) invalidates the Keychain item immediately if a new fingerprint or Face ID appearance is enrolled on the device.

Securing credentials on Android: Android Keystore and StrongBox

On Android app development builds written in Kotlin, standard SharedPreferences writes plaintext XML files to disk. To protect credentials properly, rely on the Android Keystore System:

  • Hardware-backed key generation: Generate AES-256-GCM master keys or ECDSA signing keys inside the Android Keystore, which executes cryptographic operations inside a Trusted Execution Environment (TEE) or a dedicated StrongBox Keymaster hardware security chip (setIsStrongBoxBacked(true) with TEE fallback).
  • Modern encrypted storage: Android's older EncryptedSharedPreferences wrapper is deprecated in favor of Jetpack DataStore paired with Google Tink (AndroidKeysetManager) utilizing android-keystore:// master key URIs. For relational data on either platform, encrypt SQLite databases using SQLCipher (via Room's SupportFactory on Android or GRDB/SQLCipher on iOS) with a 256-bit random key wrapped by the hardware keystore.
Storage MechanismUnderlying ProtectionSurvives Cloud/Device Backup?Safe for Bearer Tokens & PII?
iOS UserDefaults / Android SharedPreferencesPlaintext XML or binary plist in app sandboxYes, by default unless excludedNever
React Native AsyncStorageUnencrypted SQLite / plaintext files on diskYes, by defaultNever
iOS Keychain (WhenUnlockedThisDeviceOnly)AES-256-GCM key hierarchy tied to Secure Enclave UIDExcluded (ThisDeviceOnly)Yes
Android Keystore + Tink / Jetpack DataStoreKeys bound to TEE or StrongBox hardware moduleKeystore keys are non-exportableYes
SQLCipher Encrypted SQLite DatabaseFull-database AES-256 page encryptionExcluded via allowBackup="false" & isExcludedFromBackupYes (when key lives in Keychain/Keystore)

Eliminating side-channel leaks: backups, snapshots, clipboard, and logs

Even when your database and token store are encrypted, data leaks out through OS convenience features if you do not lock them down in your mobile app architecture:

  1. Disable OS cloud backups for sensitive files: On Android, set android:allowBackup="false" in AndroidManifest.xml, or define <backup-rules> and <data-extraction-rules> excluding databases and preferences. On iOS, set URLResourceValues.isExcludedFromBackup = true and enable NSFileProtectionComplete.
  2. Blank the app switcher snapshot: In applicationWillResignActive on iOS, overlay a privacy splash view; on Android, apply WindowManager.LayoutParams.FLAG_SECURE on screens displaying payment cards, balances, or clinical records.
  3. Expire clipboard data and strip release logs: On iOS, use UIPasteboard.general.setItems(_:options:) with .localOnly: true and a 60-second .expirationDate. Enforce an R8 rule (-assumenosideeffects class android.util.Log { *; }) on Android and compiler flags on iOS so debug logs never ship in production.

Layer 2: Phishing-resistant authentication and session lifecycle (MASVS-AUTH)

Authentication on mobile has two failure modes: weak protocol design between the client and the identity provider, and weak local session binding on the handset.

OAuth 2.0 with PKCE (RFC 7636) for public mobile clients

A mobile app is an OAuth 2.0 public client because it cannot keep a static client_secret confidential. To prevent malicious apps on the same handset from intercepting authorization codes via custom URL schemes, every mobile app must enforce Proof Key for Code Exchange (PKCE) under RFC 7636:

  1. Before login, the app generates a high-entropy random code_verifier (43 to 128 characters).
  2. The app hashes the code_verifier with SHA-256 (S256) to produce the code_challenge and sends only the challenge to the authorization endpoint via a system browser session (ASWebAuthenticationSession on iOS or Android Custom Tabs, never an embedded WebView).
  3. When the authorization server redirects back with an authorization code, the app sends the original code_verifier over TLS to the token endpoint. Always pair PKCE with verified Universal Links (iOS) and Android App Links over HTTPS.

FIDO2 Passkeys and cryptographic biometric binding

SMS one-time passwords (OTPs) are restricted in modern identity standards, including NIST SP 800-63B Digital Identity Guidelines, because SIM swapping and real-time phishing proxies routinely defeat them. In 2026, the gold standard for mobile authentication is Passkeys, built on the FIDO2 and WebAuthn standards. Using ASAuthorizationController on iOS and CredentialManager on Android, the device generates an asymmetric key pair bound exclusively to your relying party domain (rpId), keeping the private key inside the Secure Enclave or Google Password Manager hardware vault.

Similarly, when implementing local step-up authentication ("Scan Face ID to approve transfer"), never branch on a simple boolean callback:

  • The vulnerable pattern (Event-Bound Biometrics): Calling LAContext.evaluatePolicy or BiometricPrompt.authenticate(promptInfo) without a cryptographic object and executing if (success) { sendTransfer() }. On a rooted phone, an attacker attaches Frida, hooks onAuthenticationSucceeded, and triggers the callback in seconds.
  • The secure pattern (Cryptographic-Bound Biometrics): Generate a private signing or encryption key inside the Secure Enclave or Android Keystore with setUserAuthenticationRequired(true) and pass it via BiometricPrompt.CryptoObject or SecAccessControl (.biometryCurrentSet). The hardware module physically refuses to sign or decrypt the payload unless the biometric sensor verifies the user inside the trusted execution environment.
If a biometric check in your mobile app only flips a boolean in application memory, an attacker with Frida will bypass it in ten seconds. Bind the biometric sensor to a cryptographic key inside the Secure Enclave or StrongBox so the hardware itself gates the secret.

Layer 3: Network transport security and SPKI public-key pinning (MASVS-NETWORK)

Every byte travelling between a mobile handset and your backend crosses untrusted networks, including public Wi-Fi or an attacker's laptop running mitmproxy or Burp Suite.

Lock down the OS network configuration first so no developer or third-party SDK can introduce cleartext HTTP calls: keep NSAppTransportSecurity (ATS) strict in Info.plist on iOS, and set <base-config cleartextTrafficPermitted="false"> inside res/xml/network_security_config.xml on Android.

Standard TLS trusts over 150 system root Certificate Authorities (CAs), and an attacker examining your app can manually install a custom root CA certificate onto their own phone (mitmproxy-ca-cert.pem) to inspect HTTPS traffic. High-risk apps counter this with pinning, but naive leaf-certificate pinning is also the number-one cause of self-inflicted outages when certificates rotate. Follow three rules under OWASP MASTG guidelines:

  1. Pin the SPKI public key hash, not the leaf certificate: Pin the Base64-encoded SHA-256 hash of the Subject Public Key Info (SPKI) so routine renewals using the same key pair or intermediate CA remain valid.
  2. Always include at least one off-CA backup pin: Configure NSPinnedDomains on iOS and <pin-set> in Android network_security_config.xml with your primary SPKI hash plus a backup SPKI hash from an independent backup Certificate Authority.
  3. Set an expiration date on pin sets: Use <pin-set expiration="YYYY-MM-DD"> and ATS pin expiration so older app versions degrade gracefully to OS system trust rather than permanently bricking connectivity.

Layer 4: Device integrity, binary attestation, and code hardening (MASVS-RESILIENCE & MASVS-CODE)

Even with TLS 1.3 and SPKI pinning enabled, an attacker with root access on their own test phone can use Frida or Objection (objection explore --startup-command "android sslpinning disable") to hook the TLS library in memory and bypass pinning on their handset. Once they observe your API structure, they will try to automate credential stuffing, scrape data, or submit modified payloads to your backend. This is where code resilience (MASVS-RESILIENCE) and hardware-backed device attestation intersect.

How hardware attestation, biometric key unlocking, and OAuth 2.0 PKCE combine in a zero-trust mobile API flow

Hardware attestation: Apple App Attest and Google Play Integrity API

Client-side root or jailbreak checks (such as checking whether /Applications/Cydia.app or /system/xbin/su exists) are easily patched out of the binary. Modern mobile security moves integrity verification to a cryptographic challenge-response between the device's secure hardware and your backend server:

  • On iOS (Apple App Attest): Using DCAppAttestService in DeviceCheck, the Secure Enclave generates a hardware-bound key and Apple certifies that it belongs to a genuine Apple device running an unmodified build signed with your Team ID. For sensitive API requests, your backend sends a one-time challenge nonce, and the app signs a cryptographic assertion (generateAssertion) over the request payload.
  • On Android (Google Play Integrity API): Using StandardIntegrityManager, your app requests an integrity verdict token signed by Google's servers based on hardware attestation from the Android Keystore. Your backend verifies appRecognitionVerdict (PLAY_RECOGNIZED), deviceRecognitionVerdict (MEETS_DEVICE_INTEGRITY or MEETS_STRONG_INTEGRITY), and requestHash (binding the token to the SHA-256 hash of the specific request payload).

Binary obfuscation and cross-platform considerations

Whether you build native apps or use cross-platform frameworks (compared in our native vs cross-platform guide and React Native vs Flutter breakdown), harden the release binary so static analysis is expensive:

  • Native Android & iOS: Enable isMinifyEnabled = true and isShrinkResources = true with R8 full mode (android.enableR8.fullMode=true) on Android, and enable STRIP_INSTALLED_PRODUCT = YES and STRIP_SWIFT_SYMBOLS = YES in Xcode release builds.
  • React Native app development & Flutter app development: Compile JavaScript to Hermes bytecode (.hbc) with stripped source maps in React Native, and compile Flutter release builds ahead-of-time (AOT) with --obfuscate --split-debug-info=/<symbol-directory> so Dart class and function names are stripped from libapp.so.

Complete OWASP MASVS v2.1 pre-launch checklist

Before any release candidate ships to App Store Connect or the Google Play Console, run through this verification matrix covering all eight control groups of the OWASP MASVS v2.1 standard. We integrate these checks directly into our how to build a mobile app delivery pipeline so security never becomes a last-minute launch blocker.

MASVS DomainControl ID & ObjectiveConcrete Pre-Launch Verification Check
MASVS-STORAGESTORAGE-1 / STORAGE-2: Secure local dataStore tokens and keys in iOS Keychain (WhenUnlockedThisDeviceOnly) or Android Keystore + Tink/SQLCipher; verify android:allowBackup="false", NSFileProtectionComplete, and FLAG_SECURE
MASVS-CRYPTOCRYPTO-1 / CRYPTO-2: Strong hardware keysUse AES-256-GCM or ChaCha20-Poly1305 and ECDSA P-256 / Ed25519; confirm zero hardcoded keys or static IVs; enforce Secure Enclave or StrongBox key generation
MASVS-AUTHAUTH-1 to AUTH-3: Phishing-resistant authEnforce OAuth 2.0 PKCE (RFC 7636) or FIDO2 Passkeys; bind biometrics to a hardware CryptoObject / SecAccessControl key; verify server-side BOLA checks on all endpoints
MASVS-NETWORKNETWORK-1 / NETWORK-2: TLS 1.3 and SPKI pinningEnforce TLS 1.3 via ATS and network_security_config.xml with zero cleartext fallbacks; for high-risk apps, pin SPKI SHA-256 hashes with an off-CA backup pin and expiration date
MASVS-PLATFORMPLATFORM-1 to PLATFORM-3: Safe IPC & WebViewsSet android:exported="false" on non-public Android components; verify Universal Links / App Links; disable WebView local file access and unused JS bridges
MASVS-CODECODE-1 to CODE-4: Signed builds & clean SBOMsSign release builds with production certs (debuggable=false), validate deep-link inputs against strict schemas, and pass SCA dependency scans (CycloneDX SBOM + zero critical CVEs)
MASVS-RESILIENCERESILIENCE-1 to RESILIENCE-4: Attestation & obfuscationVerify Apple App Attest and Google Play Integrity API tokens on sensitive API calls; verify R8 full mode, Flutter --obfuscate, or Hermes bytecode compilation
MASVS-PRIVACYPRIVACY-1 to PRIVACY-4: Manifests & log redactionMatch Apple PrivacyInfo.xcprivacy and Google Play Data Safety declarations to SDK usage; redact PII and tokens from crash/system logs; provide in-app account deletion

For regulated products in fintech (where PCI Security Standards Council Mobile Payment Acceptance guidelines and PSD2 Strong Customer Authentication apply) or healthtech (where HIPAA and GDPR Article 32 security of processing apply), archiving the test evidence from this table gives compliance auditors traceable proof of control enforcement. Factoring this verification work into your initial mobile app development cost estimate prevents expensive post-launch rewrites.

How to test mobile app security in CI/CD and before release

A security checklist only protects users if you test what the compiled binary actually does on a physical phone rather than trusting what the source code intended to do.

1. Automated CI/CD security pipeline (Every Pull Request)

Every commit in a professional mobile app development repository should pass three automated gates before merge:

  • Secret and SAST scanning: Run gitleaks to catch accidental secret commits, paired with Semgrep mobile rulesets targeting Swift, Kotlin, and TypeScript/Dart patterns.
  • Binary analysis with MobSF: Run Mobile Security Framework (MobSF) in headless Docker mode against compiled .apk and .ipa artifacts in CI to check permissions, compiler hardening flags (PIE, ARC, R8 obfuscation), and high-entropy strings.
  • Software Composition Analysis (SCA): Run osv-scanner, Dependabot, or Snyk against lockfiles to catch vulnerable third-party SDKs (M2).

2. Manual dynamic penetration testing against OWASP MASTG (Pre-Release)

Before launch, run a structured manual test on a physical rooted/jailbroken test handset using the OWASP MASTG methodology:

  1. Filesystem inspection: Install the release build, execute core workflows, and inspect /data/data/<package> (Android) or /var/mobile/Containers/Data/Application/<UUID> (iOS) to confirm zero plaintext tokens or unencrypted PII exist in SQLite databases, plists, caches, or logs.
  2. Runtime instrumentation: Attach Frida and Objection to attempt Keychain/Keystore dumps, hook biometric callbacks, and inspect memory for lingering secrets after logout.
  3. Network interception and Backend BOLA testing: Route traffic through Burp Suite or mitmproxy with a custom root CA installed. Confirm that pinned endpoints reject the proxy certificate, then bypass pinning via Frida to test every backend endpoint for Broken Object Level Authorization (BOLA), rate-limit bypasses, and missing App Attest or Play Integrity verification. As we highlight in our analysis of 2026 mobile app development trends, hardware attestation and passkey adoption are rapidly becoming baseline defenses against automated API abuse.
Shipping a mobile app that handles sensitive financial, health, or enterprise data?
Book a mobile security & architecture review

Occasional field notes on building software, no spam

Protected by Cloudflare Turnstile · Privacy · Terms

Artem Zaitsev
Artem ZaitsevCTO · Idealogic Development OÜ

CTO and Co-founder at Idealogic. Directing engineering, systems architecture, security, and full-stack delivery across web, mobile, and blockchain.

Frequently asked questions

  • Mobile app security is the engineering discipline of protecting application data, cryptographic keys, authentication flows, and business logic when the compiled binary runs on hardware you do not control. Unlike a web backend inside your cloud VPC, an iOS IPA or Android APK is downloaded directly to a user's or attacker's phone, where anyone with jadx and Frida can inspect local files, hook runtime functions, and forge API requests.

  • The OWASP Mobile Top 10 (updated in 2024) is a high-level awareness list of the ten most common risk categories affecting mobile software, such as improper credential usage (M1) and insecure data storage (M9). The OWASP Mobile Application Security Verification Standard (MASVS v2.1) is the actionable engineering framework underneath it, organizing testable security controls across storage, cryptography, authentication, networking, platform APIs, code quality, resilience, and privacy.

  • Never store tokens or keys in Android SharedPreferences, iOS NSUserDefaults, React Native AsyncStorage, or unencrypted SQLite files. On iOS, store sensitive credentials in the Keychain using kSecAttrAccessibleWhenUnlockedThisDeviceOnly backed by the Secure Enclave. On Android, generate and wrap encryption keys inside the Android Keystore System backed by a dedicated StrongBox hardware module when available, and persist encrypted values using Jetpack DataStore with Tink or SQLCipher.

  • No. Enforce TLS 1.3 across every app by default, but reserve public-key pinning for high-risk applications in fintech, healthtech, or enterprise identity where attackers actively attempt man-in-the-middle interception on compromised devices. When you implement pinning, never pin the leaf certificate directly. Pin the SHA-256 hash of the Subject Public Key Info (SPKI) along with at least one backup SPKI hash from an independent certificate authority.

  • Biometric checks fail when developers implement event-bound authentication instead of cryptographic-bound authentication. If your code calls LocalAuthentication on iOS or BiometricPrompt on Android and branches on a simple true or false boolean callback, an attacker running Frida on a rooted device can hook that callback and force it to return true in seconds. Always pass a CryptoObject or SecAccessControl flag that requires hardware to unlock a cryptographic key.

  • Because attackers can extract API endpoints from your binary and replay requests from Python scripts or modified APKs, backend servers need proof that a request came from an untampered binary running on genuine silicon. Apple App Attest and the Google Play Integrity API use hardware-backed keys inside the device to sign a cryptographic attestation statement tied to a server challenge nonce before your API gateway honors sensitive mutations.

  • Cross-platform apps share the exact same OS sandboxes and hardware keystores as native apps when configured properly using native bridges like react-native-keychain or flutter_secure_storage. The main difference lies in reverse-engineering ergonomics. React Native ships Hermes bytecode and Flutter compiles Dart ahead-of-time (AOT) into libapp.so, but plain JavaScript bundle strings or unstripped Dart symbols are easy to extract if developers hardcode secrets in client configuration files.

  • An automated static and dynamic baseline scan using MobSF, Semgrep, and dependency auditing takes one to two days and should run continuously in CI/CD on every pull request. A full manual penetration test conducted against the OWASP Mobile Application Security Testing Guide (MASTG), covering binary decompilation, Frida runtime hooking, TLS pinning bypass attempts, and API object-level authorization testing, typically takes five to ten engineering days.

Still unanswered
Ask us directly

A senior engineer replies under 4 hours.

Related expertise