<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-mobile-app-hardening
description: >-
  Apply defensive security controls to mobile applications including code
  obfuscation, certificate pinning, anti-tampering, root/jailbreak detection,
  secure storage implementation, and RASP integration for Android and iOS.
domain: cybersecurity
subdomain: mobile-security
tags:
  - hardening
  - obfuscation
  - certificate-pinning
  - anti-tampering
  - rasp
  - proguard
  - secure-storage
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1406", "T1407"]
  owasp-mobile: ["M2", "M5", "M8", "M9"]
  tools: ["proguard", "r8", "dexguard", "swiftshield"]
---

# Implementing Mobile App Hardening

## Overview

Mobile app hardening applies layered defenses against reverse engineering,
tampering, and runtime attacks. Covers code obfuscation, integrity verification,
secure key storage, certificate pinning implementation, and runtime application
self-protection (RASP) for both Android and iOS.

## Workflow

### Step 1: Code Obfuscation

```groovy
// Android: ProGuard/R8 (build.gradle)
android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                'proguard-rules.pro'
        }
    }
}

// proguard-rules.pro
-keep class com.target.api.models.** { *; }
-keepclassmembers class * implements java.io.Serializable { *; }
-obfuscationDictionary dict.txt
-classobfuscationdictionary dict.txt
-packageobfuscationdictionary dict.txt
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
```

```swift
// iOS: Use SwiftShield for class/method name obfuscation
// swiftshield obfuscate --project-file App.xcodeproj
// Or use commercial tools: iXGuard, Arxan
```

### Step 2: Certificate Pinning Implementation

```kotlin
// Android: OkHttp certificate pinning
val certificatePinner = CertificatePinner.Builder()
    .add("api.target.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .add("api.target.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")  // Backup
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build()

// Network security config (res/xml/network_security_config.xml)
// <network-security-config>
//   <domain-config>
//     <domain includeSubdomains="true">api.target.com</domain>
//     <pin-set expiration="2025-01-01">
//       <pin digest="SHA-256">base64pin==</pin>
//       <pin digest="SHA-256">backuppin==</pin>
//     </pin-set>
//   </domain-config>
// </network-security-config>
```

```swift
// iOS: URLSession certificate pinning
class PinningDelegate: NSObject, URLSessionDelegate {
    let pinnedCertHash = "expected_sha256_hash"

    func urlSession(_ session: URLSession,
                    didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard let serverTrust = challenge.protectionSpace.serverTrust,
              let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }
        let serverCertData = SecCertificateCopyData(certificate) as Data
        let serverHash = sha256(data: serverCertData)
        if serverHash == pinnedCertHash {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}
```

### Step 3: Secure Storage

```kotlin
// Android: EncryptedSharedPreferences
val masterKey = MasterKey.Builder(context)
    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
    .build()

val encryptedPrefs = EncryptedSharedPreferences.create(
    context, "secure_prefs", masterKey,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

// Android Keystore for key material
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
keyGenerator.init(KeyGenParameterSpec.Builder("myKey",
    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
    .setUserAuthenticationRequired(true)
    .build())
```

```swift
// iOS: Keychain Services
let query: [String: Any] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrAccount as String: "auth_token",
    kSecValueData as String: tokenData,
    kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
```

### Step 4: Anti-Tampering and Integrity Checks

```kotlin
// Android: APK signature verification at runtime
fun verifySignature(context: Context): Boolean {
    val packageInfo = context.packageManager.getPackageInfo(
        context.packageName, PackageManager.GET_SIGNING_CERTIFICATES)
    val signatures = packageInfo.signingInfo.apkContentsSigners
    val expectedHash = "expected_cert_sha256"
    return signatures.any { sig ->
        val digest = MessageDigest.getInstance("SHA-256")
        val hash = digest.digest(sig.toByteArray())
        hash.toHexString() == expectedHash
    }
}
```

```c
// Native anti-debug (Android NDK)
#include <sys/ptrace.h>
void anti_debug() {
    if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
        // Debugger attached — exit or degrade
        exit(1);
    }
}

// Check /proc/self/status for TracerPid
void check_tracer() {
    char buf[512];
    FILE *f = fopen("/proc/self/status", "r");
    while (fgets(buf, sizeof(buf), f)) {
        if (strncmp(buf, "TracerPid:", 10) == 0) {
            int pid = atoi(buf + 10);
            if (pid != 0) exit(1);
        }
    }
    fclose(f);
}
```

### Step 5: Runtime Application Self-Protection (RASP)

```
RASP Controls Checklist:
├── Root/jailbreak detection with response strategy
├── Debugger detection (ptrace, sysctl, isDebuggerAttached)
├── Frida/Xposed detection (port scanning, artifact checks)
├── Emulator detection (build properties, sensor checks)
├── Hooking framework detection (PLT/GOT integrity)
├── Code integrity verification (checksum validation)
├── Screen recording/screenshot prevention
├── Secure keyboard enforcement for sensitive input
└── App backgrounding data masking
```

## Detection Opportunities

| Signal | Source | Description |
|--------|--------|-------------|
| Repackaged APK | Signature check | Different signing certificate |
| Debugger attached | TracerPid | Non-zero tracer process |
| Frida detected | Port scan | Port 27042 open |
| Rooted device | File checks | Su binary present |

```yaml
title: Mobile App Hardening Detection
id: c2c9b66b-2432-4b2e-ba4b-42fd859c3ea3
status: experimental
description: Detects suspicious activity related to implementing mobile app hardening techniques in mobile security context
logsource:
  category: application
  product: android
detection:
  selection:
    EventType: error
  condition: selection
level: medium
tags:
  - attack.t1406
  - attack.t1407
  - attack.initial_access
falsepositives:
  - Mobile device management platform enforcing security policies
```

## Verification

- [ ] Code obfuscation applied and verified via decompilation
- [ ] Certificate pinning implemented with backup pins
- [ ] Sensitive data stored in Keystore/Keychain only
- [ ] Anti-tampering checks active at runtime
- [ ] Anti-debug protections implemented
- [ ] RASP controls deployed and tested

## References

- [OWASP MASVS — Resilience Requirements](https://mas.owasp.org/MASVS/)
- [Android Security Best Practices](https://developer.android.com/topic/security/best-practices)
- [iOS App Security Guide](https://developer.apple.com/documentation/security)
- [MITRE T1406](https://attack.mitre.org/techniques/T1406/)
