What is mobile app security?

Learn what mobile app security is, the threats that target iOS and Android apps, and how to build it into your CI/CD workflow.

Mobile app security is the practice of protecting iOS and Android apps from attack across their full lifecycle, from the code you write to the binary users install. It combines secure coding, data protection, code signing, and security testing, with much of the work happening inside your CI/CD workflow.

What is mobile app security?

Mobile app security is everything you do to stop attackers from stealing data through your app, and from tampering with or impersonating it. That covers how you write code, how you store user data, how you protect the credentials that build and sign your releases, and how you test for weaknesses before each release reaches a store.

Runtime protections get most of the attention: obfuscation, jailbreak detection, anti-tampering SDKs. Those matter, but they describe hardening a finished binary. The part that decides whether you have anything trustworthy to harden is upstream. A leaked API key in a build log puts every user at risk before the app ever runs on a device. So does a signing certificate committed to a repository, or a compromised dependency. Code signing is the clearest example: it exists so a device can prove your app came from you, and it only works if the private keys stay private through every build.

The threat model is also different from anything server-side. Your app runs on hardware you don't control, next to apps you didn't write, on networks you can't trust. Anyone can download your binary and decompile it. Mobile app security means designing for that reality instead of hoping nobody looks.

How does mobile app security work?

Mobile app security works in layers. Code-level protections stop injection and logic flaws, data protections encrypt what the app stores and transmits, code signing proves the binary came from you and hasn't been modified, and security testing checks all of it before release. No single layer is enough because each one covers a failure mode of the others.

The code layer is where vulnerabilities are born: unvalidated input, secrets hardcoded in source, verbose logging that leaks tokens. Platform APIs solve most of this for you. On iOS, that means Keychain Services for credentials. On Android, the Android Keystore system keeps cryptographic keys non-exportable: the app process can use them but never extract them. On devices with secure hardware, the keys stay inside it.

The data layer protects information in transit and at rest. iOS enforces HTTPS through App Transport Security. Android does the same through the network security configuration file. Anything sensitive belongs in encrypted storage keyed by the platform keystore, never in plain UserDefaults or SharedPreferences.

The signing layer is the trust chain. On iOS it works as a sequence:

  1. Apple issues a signing certificate tied to your developer account.
  2. A provisioning profile binds that certificate to your app ID and permitted devices.
  3. Xcode or your CI signs the archive with the certificate and embeds the profile.
  4. The device verifies the signature at install and again at launch, and refuses to run an app whose signature is invalid.

Android follows the same logic with a keystore you generate yourself. With Play App Signing, the default for new Play apps, Google holds the app signing key and your keystore holds an upload key that Google can reset if it leaks. iOS code signing has more moving parts, but on both platforms the rule is identical: whoever holds the signing keys can publish as you.

The testing layer verifies the other three. Static analysis (SAST) scans source for known-bad patterns while dynamic analysis (DAST) probes the running app. Mobile app security testing (MAST) tools apply these techniques to mobile apps, including analysis of the compiled IPA or APK. The OWASP Mobile Application Security project publishes the industry baseline for what to test: the MASVS standard and its companion testing guide.

Mobile app security threats at each stage of the app lifecycle, from code and build through signing and distribution to runtime
Mobile app security threats at each stage of the app lifecycle, from code and build through signing and distribution to runtime.

Because the build stage sits in the middle of that chain, your workflow configuration is itself a security control. Here's an Android build where the signing credentials never touch the repository:

# bitrise.yml - the keystore and its passwords come from the # Code signing page in Project settings, not from source control workflows: release: steps: - git-clone@8: {} - android-build@1: inputs: - module: app - variant: release # Sign APK reads BITRISEIO_ANDROID_KEYSTORE_URL, # BITRISEIO_ANDROID_KEYSTORE_PASSWORD, and the key alias # automatically from the uploaded keystore file - sign-apk@2: {}

Why mobile app security matters for mobile development

A mobile security failure costs more than a comparable web incident because you can't patch instantly. Every fix ships as a new binary, through store review, onto devices that update on their own schedule. A vulnerability that a web team could hotfix in twenty minutes can stay live in a mobile app for days, weeks, or even longer if automatic updates aren’t enabled. That patch gap is why prevention has to happen in the workflow, before release.

The scale of the threat is measurable. In the Verizon 2025 Mobile Security Index, 85% of organizations reported an increase in mobile attacks. Apple's own numbers show the same pressure: Apple rejected over 2 million App Store submissions in 2025, including over 443,000 for privacy violations, and also prevented $2.2 billion in potentially fraudulent transactions.

The store review process exists to protect users. An insecure data practice that slips through your own review becomes a store rejection at the worst possible moment: release day, with a marketing campaign already scheduled and a fix now facing another review cycle.

Teams that treat security as a pre-release audit create a bottleneck: findings arrive late, so fixes are expensive and releases slip. Teams that practice DevSecOps move the same checks into the workflow, where a failed scan is one more red build to fix cheaply. 

Mobile app security best practices

High-return mobile app security work is not glamorous. Keep credentials out of the repository and out of the binary, encrypt what you store, lock down what you transmit, verify what you depend on, and test the binary you actually ship. Each practice below names the specific setting or API to use.

1. Keep signing credentials out of source control. Upload your Android keystore and iOS certificates to your CI provider's encrypted storage instead of committing them. On Bitrise, that's the Code signing page under Project settings. For local iOS development, enable the "Automatically manage signing" checkbox in Xcode's Signing & Capabilities tab. For release builds, let CI hold the distribution certificate so it never lives on laptops.

2. Treat CI secrets like production credentials. Store API keys and tokens as encrypted secrets, not plain environment variables in config files. Keep pull request exposure off by default: a malicious PR that prints your secrets is a well-known CI attack. Rotate any secret that has ever appeared in a log, because redaction can't retroactively protect a value that leaked before it was registered.

3. Use platform storage for anything sensitive. Tokens and credentials belong in the iOS Keychain (with an accessibility class like kSecAttrAccessibleWhenUnlockedThisDeviceOnly) or in encrypted storage backed by the Android Keystore. Plain UserDefaults and SharedPreferences are readable on compromised devices and show up in backups.

4. Don't ship API keys inside the app. Hardcoding a key in source or adding it to Info.plist is common, and some SDK providers encourage it: Mapbox's iOS SDK docs have you set your access token in Info.plist. Anyone who unzips your IPA or APK can read that key back in minutes and use it to make requests billed to your account. Encrypting the key inside the binary only stops inexperienced attackers, because everything needed to decrypt it ships in the same binary.

A better pattern is to have your server send the key when the app launches, then store it in the Keychain or Keystore-backed storage from practice 3. The key never sits in your build artifacts, and you can rotate it at any time without shipping a new release. For keys that grant real privileges, go one step further and keep them off the device: your backend holds the key and calls the third-party API for the app. Pair either approach with app attestation (practice 5) so only genuine copies of your app can reach those endpoints. Keys a provider designs to be public still deserve the tightest scope restrictions it offers.

5. Check that requests come from your real app. Your API can't tell a genuine install from a modified copy or a script replaying requests. A modified game client, for example, can report a score the player never earned. On iOS, the App Attest service (DCAppAttestService in the DeviceCheck framework) creates a hardware-backed key and has Apple attest that it belongs to a genuine instance of your app. After that, the app signs assertions your server verifies on sensitive requests. Apple's guide to establishing your app's integrity walks through the full flow. On Android, the Play Integrity API does the same job. Check isSupported before calling App Attest (it's false in the Simulator and in most app extensions) and fall back gracefully. Treat attestation results as one risk signal your server weighs alongside its own auth and rate limiting.

6. Don't punch holes in transport security. Keep App Transport Security intact rather than adding NSAllowsArbitraryLoads to Info.plist as a "temporary" fix. On Android, cleartext traffic is blocked by default for apps targeting API level 28 or higher, so don't turn it back on with cleartextTrafficPermitted="true" in your network security configuration. If you adopt certificate pinning, plan the rotation path first: a pinned certificate that expires without a backup pin bricks networking for every installed copy of your app.

7. Verify your dependencies. Third-party SDKs run with your app's full permissions and are a favorite supply-chain target. Commit your lockfiles (Package.resolved for Swift Package Manager, gradle.lockfile for Gradle) plus Gradle's verification-metadata.xml, which checks each dependency's checksum and signature. Then run a dependency scanner in the workflow so a hijacked package version fails the build instead of shipping.

8. Test the binary, not just the source. Static analysis on source misses what only exists after compilation: embedded keys and misconfigured entitlements. Run MobSF or another MAST tool against the built IPA or APK in your release workflow, so every candidate gets the same inspection an attacker would start with.

Mobile app security vs web application security

Both disciplines defend against the same broad vulnerability classes, and OWASP maintains a top-ten list for each. The difference is the constraints. A web app runs on servers you control and patches in minutes. A mobile app runs on hardware you'll never see and ships its full binary to anyone who wants to inspect it. It patches only as fast as store review plus user adoption allows.

Dimension Mobile app security Web application security
Where code runs
User's device; binary fully inspectable
Your servers; code stays hidden
Patch speed
Days: new build, store review, user updates
Minutes: deploy to your own servers
Credential storage
Keychain, Android Keystore on device
Server-side sessions and cookies
Transport control
ATS, network security config in the app
TLS termination you configure directly
Distribution gatekeeper
App Store and Google Play review
None; you publish directly
Installed versions
Long tail of old installs stays vulnerable
Every user runs the latest deploy
Reverse engineering
Constant; assume full binary access
Limited to what the client receives

The practical consequence: treat the mobile client as hostile territory. Never ship a secret in the binary or trust client-side validation alone, and design APIs assuming the caller may be a modified copy of your app.

How Bitrise handles mobile app security

Bitrise covers the build and release side of mobile app security: encrypted secrets and managed code signing files, plus security testing Steps that run inside your workflow. The platform's job is to make the secure path the default path, so protecting credentials doesn't depend on every engineer remembering to.

Secrets on Bitrise are encrypted environment variables managed on the Secrets page of the Workflow Editor. Their values stay out of bitrise.yml entirely, and the Bitrise CLI redacts them from build logs, printing [REDACTED] wherever a value would appear. Two controls matter for your threat model. "Expose for Pull Requests?" is off by default, so a fork can't submit a PR that exfiltrates your keys. And marking a secret as protected is irreversible: after that, nobody can view or edit the value, including the person who created it. The only way to change a protected secret is to delete and recreate it, which is exactly the property you want for a distribution certificate password. The secrets documentation covers the full behavior.

Code signing files get the same treatment. You upload your iOS certificates and provisioning profiles, plus your Android keystore, once, to encrypted storage on the Code signing page in your Project settings, and they're delivered to build machines only when a workflow needs them. For iOS, automatic provisioning connects to Apple through an App Store Connect API key, downloads or creates the provisioning profiles each build needs, renews them when they expire, and registers new test devices along the way. That removes one of the most stubborn causes of red iOS builds and, just as important, removes the temptation to share a profile through Slack. The iOS code signing documentation walks through both the automatic and manual paths. For Android, the uploaded keystore is exposed to Steps through BITRISEIO_ANDROID_KEYSTORE_URL and its companion password variables, which the Android Sign Step consumes without any of them appearing in your config.

On top of that foundation, the Step library includes security testing integrations, Fortify on Demand Mobile Assessment among them, and a Script Step can run MobSF or other open-source scanners against your built artifact. Because these run as Steps in your mobile CI/CD workflow, a failed security check blocks the release the same way a failed unit test does.

See what Bitrise can do for you

Confidently build, test, and ship high-quality mobile apps with Bitrise.

Author

Szabolcs Toth

Senior Software Engineer at Bitrise

Frequently Asked Questions

What is mobile app security testing?

Mobile app security testing checks an app for vulnerabilities using a mix of static analysis on the source, dynamic analysis on the running app, and binary analysis on the compiled IPA or APK. The OWASP MASVS standard defines what to verify, and its companion testing guide (MASTG) describes how. Automate at least the static and binary checks in CI; they're the cheapest to run on every build.

Is iOS more secure than Android?

Both platforms have strong security architectures, and the gap has narrowed to the point where the comparison rarely matters for app teams. iOS enforces tighter sandboxing and a single store; modern Android counters with hardware-backed keystores and Play Protect scanning. In practice, the weakest link is almost always in the app's own code and dependencies, or in leaked credentials, rather than in the operating system.

What is the OWASP Mobile Application Security project?

It's the industry-standard reference for mobile app security, maintained by OWASP. It has two main parts: MASVS, a verification standard that defines security requirements by level, and MASTG, a testing guide with concrete procedures for verifying each requirement on iOS and Android. Use MASVS as your baseline checklist and MASTG when you need to know how to test a specific control.

Can an app be compromised after it passes store review?

Yes. Review is a snapshot, and attackers exploit that: Apple removed nearly 59,000 apps in 2025 for bait-and-switch tactics, where an app changes behavior after approval. Your own app faces the same risk through compromised SDK updates or stolen signing keys, which is why dependency verification and credential protection stay important long after launch.