Admin

Sep 9, 2025

Admin

Sep 9, 2025

Admin

Sep 9, 2025

OWASP Top 10 with Code Examples: Android Quick Guide

OWASP Top 10 with Code Examples: Android Quick Guide

A quick guide to the OWASP Top 10 for Android developers with secure coding examples in Java and Kotlin. OWASP, Android Security, MASVS, Mobile App Security, Secure Coding, Kotlin, Java

Introduction

Android apps face the same security risks as web applications — weak authentication, insecure storage, outdated libraries — but also unique mobile-specific challenges. This quick guide summarizes the OWASP Top 10 risks with Android code examples to help developers secure their apps.

1. Broken Access Control

Why It Matters: Unauthorized users may access protected activities or APIs.

Secure Example (Kotlin + Firebase Rules):

// Only allow access if UID matches document owner
match /users/{userId} {
  allow read, write: if request.auth != null && request.auth.uid == userId;
}

2. Cryptographic Failures

Why It Matters: Insecure storage of sensitive data can expose tokens or passwords.

Secure Example (Java + Keystore):

KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
        "appKey",
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

KeyGenerator gen = KeyGenerator.getInstance("AES", "AndroidKeyStore");
gen.init(spec);
SecretKey key = gen.generateKey();

3. Injection

Why It Matters: SQLite queries vulnerable to injection can leak user data.

Secure Example (Java):

// ❌ Insecure
db.rawQuery("SELECT * FROM users WHERE name = '" + name + "'", null);

// ✅ Secure with bind arguments
Cursor c = db.rawQuery("SELECT * FROM users WHERE name = ?", new String[]{name});

4. Insecure Design

Why It Matters: Relying only on client-side checks is unsafe.

Secure Example (Kotlin):

// Validate permissions server-side, not only in app
fun canTransfer(userId: String, actor: Actor): Boolean {
    return actor.role == "ADMIN" || actor.userId == userId
}

5. Security Misconfiguration

Why It Matters: Leaving debuggable enabled exposes sensitive info.

Secure Example (AndroidManifest.xml):

<application
    android:debuggable="false"
    android:allowBackup="false" />

6. Vulnerable and Outdated Components

Why It Matters: Using old libraries exposes known CVEs.

Secure Example (Gradle):

// Keep dependencies updated
dependencies {
    implementation "com.google.android.material:material:1.12.0"
}

7. Identification and Authentication Failures

Why It Matters: Weak login allows account hijacking.

Secure Example (Firebase + Kotlin):

FirebaseAuth.getInstance()
    .signInWithEmailAndPassword(email, password)
    .addOnSuccessListener { /* MFA can be enforced */ }

8. Software and Data Integrity Failures

Why It Matters: Malicious updates can be injected if not verified.

Secure Example (Play Integrity API):

val integrityManager = IntegrityManagerFactory.create(context)
val request = IntegrityTokenRequest.builder().build()
integrityManager.requestIntegrityToken(request)

9. Security Logging and Monitoring Failures

Why It Matters: Without logs, attacks remain invisible.

Secure Example (Timber):

// Never log sensitive info
Timber.i("User login attempt for id=%s", userId)

10. Server-Side Request Forgery (SSRF)

Why It Matters: SSRF risks exist when apps proxy requests via backend APIs.

Secure Example (OkHttp + Allowlist):

val allowedHosts = listOf("api.myapp.com")

fun isAllowed(url: String): Boolean {
    val host = Uri.parse(url).host ?: return false
    return allowedHosts.contains(host)
}

Key Takeaways

  • The OWASP Top 10 applies to Android apps, not just web applications.

  • Always use Keystore, EncryptedSharedPreferences, and secure configs.

  • Validate input, patch dependencies, and enforce MFA.

  • Never log secrets or enable debuggable in production.

  • Defense-in-depth is essential: combine secure design + server checks.

👉 Quick and practical: Apply these patterns in your Android projects to reduce risks and align with OWASP MASVS standards.


Appendix: OWASP Android Quick Reference

OWASP Top 10 – Android Quick Guide (Insecure vs. Secure)

  1. Broken Access Control

Insecure:

<!-- Everyone can read/write any user data -->
<uses-permission android:name="android.permission.READ_CONTACTS" />

Secure:

// Firebase rules restrict access to owner only
match /users/{userId} {
  allow read, write: if request.auth.uid == userId;
}
  1. Cryptographic Failures

Insecure:

// Plaintext key in code
String key = "hardcoded123";

Secure:

// Generate AES key with Keystore
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder("appKey",
   KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
   .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
   .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
   .build();
  1. Injection

Insecure:

// Vulnerable to SQL Injection
db.rawQuery("SELECT * FROM users WHERE name='" + name + "'", null);

Secure:

// Use bind arguments
Cursor c = db.rawQuery("SELECT * FROM users WHERE name=?", new String[]{name});
  1. Insecure Design

Insecure:

// Client-side only check
if (isAdmin) { /* allow action */ }

Secure:

// Validate server-side
fun canTransfer(userId: String, actor: Actor): Boolean =
   actor.role == "ADMIN" || actor.userId == userId
  1. Security Misconfiguration

Insecure:

<!-- Debuggable ON in production -->
<application android:debuggable="true" />

Secure:

<application android:debuggable="false" android:allowBackup="false" />
  1. Vulnerable and Outdated Components

Insecure:

// Old dependency
implementation "com.google.android.material:material:1.0.0"

Secure:

// Updated dependency
implementation "com.google.android.material:material:1.12.0"
  1. Identification and Authentication Failures

Insecure:

// Weak custom login, no MFA
if (inputPass == storedPass) login()

Secure:

// Firebase Auth + enforce MFA
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, pass)
  1. Software and Data Integrity Failures

Insecure:

// Download update without verification
val file = URL(url).readBytes()

Secure:

// Play Integrity API check
val manager = IntegrityManagerFactory.create(context)
val request = IntegrityTokenRequest.builder().build()
manager.requestIntegrityToken(request)
  1. Security Logging and Monitoring Failures

Insecure:

Log.d("App", "Password=" + password)

Secure:

// Use Timber, redact sensitive data
Timber.i("User login attempt for id=%s", userId)
  1. Server-Side Request Forgery (SSRF)

Insecure:

// Proxy any URL from user input
val url = intent.getStringExtra("url")
OkHttpClient().newCall(Request.Builder().url(url).build()).execute()

Secure:

// Validate against allowlist
val allowedHosts = listOf("api.myapp.com")
fun isAllowed(url: String) = allowedHosts.contains(Uri.parse(url).host)


Comments (please send an email at support@droidinsights.dev)

Comments (please send an email at support@droidinsights.dev)

Comments (please send an email at support@droidinsights.dev)