๐Ÿ” Android Security and Privacy

Android App Security Best Practices

Most Android security incidents come from a handful of repeat mistakes: secrets in the APK, sensitive data in logs or plain storage, exported components, unsafe WebViews, and trusting the client. This guide organises Android security into practical layers, with code for each.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Intermediate
On this page
  1. Security layers
  2. Core principles
  3. Network security
  4. Data storage
  5. Secrets
  6. Components and intents
  7. WebViews
  8. UI and logs
  9. Release and supply chain
  10. Priorities by app type
  11. Frequently asked questions
  12. Conclusion

Android gives every app a strong sandbox, but the sandbox can't protect you from your own design decisions. Security has to be built into how you store data, talk to servers, expose components and handle authentication, and it has to assume the device and the APK can be inspected by an attacker.

Security layers

Layers of Android app security Concentric layers from the server outward: the server enforces authorization and validation; the network is protected with TLS and network security config; on-device storage uses the sandbox and Keystore-backed encryption; app components restrict exports and validate intents; the UI and WebViews avoid leaking data; and the release pipeline uses R8, signing and dependency hygiene. Release: R8, signing, dependency updates, integrity checks UI & WebView: no sensitive data in logs/screenshots, safe WebView settings Components: minimal exports, validated intents, permissions Storage: sandbox + Keystore-backed encryption, no secrets Network: TLS only, network security config Server: the real authority
The server is the final authority. Everything on the device can be observed or modified by a determined attacker.

Core principles

  • Never trust the client. Enforce authorisation, prices, limits and business rules on the server.
  • Minimise data: collect, store and log only what you need.
  • Least privilege: request minimal permissions, and export minimal components.
  • Defence in depth: combine controls, because each one can fail.

Network security

res/xml/network_security_config.xmlXML
<network-security-config>
    <!-- Disallow cleartext HTTP everywhere (default for targetSdk 28+, made explicit here) -->
    <base-config cleartextTrafficPermitted="false" />
    <!-- Allow user-installed CAs only in debug builds, e.g. for proxy debugging -->
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>
AndroidManifest.xmlXML
<application android:networkSecurityConfig="@xml/network_security_config" ... >

Never ship a custom TrustManager that accepts all certificates or a HostnameVerifier that returns true. Consider certificate pinning only with a rotation plan. See Certificate Pinning.

Data storage

  • Keep sensitive data in app-private storage, never on shared external storage.
  • Encrypt secrets and sensitive data with Keystore-backed keys. See Encrypted Data Storage and Secure Token Storage.
  • Exclude sensitive files from backups.
  • Clear user data on logout.

Secrets

Anything in the APK is extractable, including BuildConfig fields, resources, native libraries and obfuscated strings. Keep real secrets on servers and use short-lived, scoped tokens. See Secure API Keys and Secrets.

Components and intents

Export only what must be publicXML
<activity android:name=".internal.DebugMenuActivity" android:exported="false" />

<receiver android:name=".SyncReceiver" android:exported="false" />

<!-- Public deep-link entry: exported, but validate all incoming data -->
<activity android:name=".DeepLinkActivity" android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="yunoktech.com" android:pathPrefix="/orders/" />
    </intent-filter>
</activity>
Validate incoming deep link dataKotlin
val orderId = intent.data?.lastPathSegment
    ?.takeIf { it.matches(Regex("^[A-Z0-9]{4,20}$")) }   // allow-list format
    ?: return finish()
// Then load the order through the authenticated API, which enforces ownership server-side.
  • Use PendingIntent.FLAG_IMMUTABLE unless mutability is required.
  • Use explicit intents for internal communication.
  • Protect custom permissions with signature protection level when sharing between your own apps.

WebViews

  • Keep JavaScript disabled unless needed. Never enable file access from file URLs.
  • Load only your own trusted HTTPS content, and restrict navigation to allowed hosts.
  • Avoid addJavascriptInterface with untrusted content. Prefer WebViewCompat.addWebMessageListener with origin allow-lists.

UI and logs

Protect sensitive screensKotlin
// Prevent screenshots and recent-apps thumbnails on screens showing sensitive data
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
  • Never log tokens, OTPs, personal data or full API responses in release builds.
  • Mark password fields correctly (KeyboardType.Password or the password input type) so keyboards don't learn them.

Release and supply chain

  • Enable R8 (it raises the effort of reverse engineering, but isn't a security boundary).
  • Use Play App Signing, and protect upload keys. See App Signing.
  • Keep dependencies updated, remove unused SDKs, and review SDK data collection.
  • Use Play Integrity on the server for high-value actions.

Priorities by app type

Content app

TLS, minimal permissions, no secrets in the APK, safe WebViews.

Commerce app

Plus server-side price and order validation, secure tokens, and Play Integrity for checkout.

Finance or health app

Plus encrypted storage, FLAG_SECURE, biometrics for sensitive actions, strict logging, and regular security testing (MASVS).

Frequently asked questions

Does obfuscation make my app secure?

No. It slows reverse engineering. Security comes from server-side enforcement, proper storage and not shipping secrets.

Should I detect rooted devices?

Client-side root detection is easily bypassed. Prefer server-side Play Integrity verdicts for risk decisions, and don't break the app for legitimate users without reason.

Where can I find a complete checklist?

OWASP's Mobile Application Security Verification Standard (MASVS) and testing guide are comprehensive references.

Conclusion

Android security is layered: server-side authority, TLS-only networking, sandboxed and encrypted storage, minimal exported components with validated input, safe WebViews and logging, and a secure release pipeline. Fix the common mistakes first, then deepen for higher-risk apps.

Next step: understand the foundation of on-device cryptography in Android Keystore Explained.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Security is easiest to get right when it is part of how you build from the first screen. Strengthen the Android fundamentals that secure, privacy-respecting apps are built on.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp