mobile-android-security
Skill2 starsChanged 4 months agoMITView on GitHub
SAST detection methodology for Android app security flaws (CWE-926) — exported components & intent hijacking, insecure WebView/JS-bridge, insecure data storage, deep-link/App-Link hijacking, exported ContentProvider, cleartext traffic, missing certificate pinning, mutable PendingIntent, and allowBackup. Use when reviewing an APK, decompiled smali/Java/Kotlin, or an AndroidManifest. Writes confirmed findings to findings/44-mobile-android-security.md.
In this repository49 other files it gives its agents.
- authentication-flawsSkill
- broken-access-control-idorSkill
- business-logic-flawsSkill
- cicd-and-pipeline-injectionSkill
- code-injectionSkill
- command-injectionSkill
- cors-misconfigurationSkill
- crlf-and-header-injectionSkill
- cross-site-scriptingSkill
- csrfSkill
- dependency-and-supply-chainSkill
- dom-clobbering-and-postmessageSkill
- graphql-injection-and-abuseSkill
- hardcoded-secretsSkill
- http-request-smugglingSkill
- iac-misconfigurationSkill
- information-disclosureSkill
- insecure-deserializationSkill
- insecure-randomnessSkill
- jwt-vulnerabilitiesSkill
- ldap-injectionSkill
- llm-and-ai-application-securitySkill
- mass-assignmentSkill
- memory-safetySkill
- mobile-ios-securitySkill
- nosql-injectionSkill
- oauth-oidc-saml-flawsSkill
- open-redirectSkill
- path-traversal-and-file-inclusionSkill
- prototype-pollutionSkill
- race-conditions-and-toctouSkill
- redosSkill
- sast-final-reportSkill
- sast-finding-validationSkill
- sast-methodologySkill
- security-logging-and-monitoring-failuresSkill
- security-misconfiguration-and-headersSkill
- server-side-template-injectionSkill
- session-managementSkill
- smart-contract-securitySkill
- sql-injectionSkill
- ssrfSkill
- unrestricted-file-uploadSkill
- unsafe-parsers-and-yamlSkill
- weak-cryptographySkill
- web-cache-poisoning-and-deceptionSkill
- websocket-securitySkill
- xpath-and-xml-injectionSkill
- xxeSkill
The file
Files
Mobile — Android Security — SAST Methodology
Class: Mobile — Android · CWE-926 (and CWE-919, CWE-312, CWE-749, CWE-79) · OWASP: Mobile Top 10 / MASVS
Findings file: findings/44-mobile-android-security.md
1. Overview
Android security flaws arise when an app exposes a component, sink, or data store
that a co-located malicious app (or a crafted intent/deep link) can reach
without the app's consent. The core test: does a component/API cross a trust
boundary — exported to other apps, a WebView that runs untrusted JS, a data
store readable outside the app sandbox, or a deep link that drives a privileged
action — without an enforcing permission, verification, or encryption? These
flaws live in the manifest and the app binary, not on the HTTP wire, so most
are not Burp-reproducible (see §11).
2. Where it lives
AndroidManifest.xml:<activity>/<service>/<receiver>/<provider>withandroid:exported="true"(or an<intent-filter>that implies exported) and noandroid:permission;<application>flagsusesCleartextTraffic,allowBackup,debuggable;<data>deep-link/App-Link filters.- WebView setup code in Java/Kotlin/smali (
WebView,WebSettings,addJavascriptInterface,WebViewClient.shouldOverrideUrlLoading). - Data-storage code:
SharedPreferences,SQLiteDatabase/Room,openFileOutput,getExternalStorage*,File(...)writes,MODE_WORLD_READABLE/WRITEABLE. - Deep-link / App-Link intent handling (
getIntent().getData(),onNewIntent). - Network config:
res/xml/network_security_config.xml, OkHttp/TrustManager,CertificatePinner, customHostnameVerifier. PendingIntentconstruction;res/values/strings.xmland other resources (embedded secrets / Firebase config / API keys).
3. Sources (tainted input)
Cross-app and cross-boundary inputs: intents from other apps (extras, data
URI, action), deep links / App Links (attacker-crafted https/custom-scheme
URLs), ContentProvider query/path arguments from other apps, JavaScript
running in a WebView (loaded page or injected via MITM on cleartext), files on
external/shared storage writable by other apps, and IPC via exported
services/receivers. Second-order: a value stored insecurely (SharedPreferences,
external file) then read back into a trusted operation.
4. Sinks (dangerous operations)
<!-- AndroidManifest.xml — dangerous -->
<activity android:name=".AdminActivity" android:exported="true"/> <!-- exported, no permission -->
<service android:name=".SyncService" android:exported="true"/> <!-- other apps can bind/start -->
<provider android:name=".NotesProvider" android:authorities="com.x.notes"
android:exported="true"/> <!-- SQLi / path traversal surface -->
<receiver android:name=".CmdReceiver" android:exported="true"/> <!-- broadcast injection -->
<application android:usesCleartextTraffic="true" <!-- HTTP allowed → MITM -->
android:allowBackup="true" <!-- adb backup exfil -->
android:debuggable="true"> <!-- run-as / debugger -->
<activity android:name=".DeepLinkActivity">
<intent-filter> <!-- App Link WITHOUT autoVerify -->
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="app.example.com"/>
</intent-filter>
</activity>
</application>// Java/Kotlin — dangerous WebView
WebView w = findViewById(R.id.web);
w.getSettings().setJavaScriptEnabled(true);
w.addJavascriptInterface(new NativeBridge(), "Android"); // JS→Java RCE if page untrusted (< API 17 all methods)
w.getSettings().setAllowFileAccess(true);
w.getSettings().setAllowFileAccessFromFileURLs(true);
w.getSettings().setAllowUniversalAccessFromFileURLs(true); // file:// can XHR any origin
w.loadUrl(getIntent().getData().toString()); // load attacker-controlled URL// Java — dangerous storage & IPC
getSharedPreferences("p", Context.MODE_WORLD_READABLE); // world-readable prefs (any app reads)
SharedPreferences.Editor e = sp.edit(); e.putString("token", jwt); // plaintext secret
File f = new File(getExternalStorageDirectory(), "creds.txt"); // shared storage, no sandbox
db.rawQuery("SELECT * FROM notes WHERE id=" + uri.getLastPathSegment(), null); // provider SQLi
PendingIntent.getActivity(ctx, 0, intent, 0); // MUTABLE (pre-M default) → intent hijack
String url = getIntent().getStringExtra("next"); startActivity(new Intent(ACTION_VIEW, Uri.parse(url))); // deeplink→intent redirectDangerous patterns marked above: exported="true" without android:permission,
addJavascriptInterface on an untrusted page, setAllowUniversalAccessFromFileURLs,
MODE_WORLD_READABLE, external-storage secret writes, unparameterized provider
queries, mutable PendingIntent, and App-Link filters lacking autoVerify.
5. Sanitizers / safe patterns
Safe: android:exported="false" (or omitted with no intent-filter) for
internal components; android:permission with a signature-level custom
permission on exported components; WebView with JS disabled or
addJavascriptInterface only on bundled/trusted content and @JavascriptInterface
annotation (API 17+); setAllowFileAccess(false) /
setAllowUniversalAccessFromFileURLs(false); secrets in the Android Keystore
(AndroidKeyStore) or EncryptedSharedPreferences/EncryptedFile (Jetpack
Security); MODE_PRIVATE storage inside app-internal dirs; parameterized
provider queries with a UriMatcher + projection allowlist; App Links with
android:autoVerify="true" and a hosted assetlinks.json; CertificatePinner
or a pinned network_security_config; immutable PendingIntent
(FLAG_IMMUTABLE); allowBackup="false".
Fails / not a real sanitizer:
exported="true""protected" by anormal-protection-level custom permission — any app can request it; onlysignaturebinds to your signing key.- Client-side jailbreak/root or "trusted host" string checks the user's device (and a repackager) fully controls.
- WebView URL allowlists using
startsWith/containson the host — bypassable withevil.com/app.example.com, userinfo@, or subdomain tricks. - Custom-scheme deep links with no source validation — any app/website can fire
them; only App Links with
autoVerify+assetlinks.jsonbind the domain. - Certificate pinning with a
HostnameVerifierthat returnstrue, or aTrustManagerthat accepts all chains — pinning nullified. - "Encrypting" with a hardcoded key baked into the APK (see hardcoded-secrets).
6. Detection methodology
- Inspect the manifest first — decompile with
apktool d app.apkand readAndroidManifest.xml. Enumerate every exported component and check for asignaturepermission; flag deep-link/App-Link filters,usesCleartextTraffic,allowBackup,debuggable.rg -n 'exported="true"' AndroidManifest.xml rg -n 'usesCleartextTraffic|allowBackup|android:debuggable|android:autoVerify' AndroidManifest.xml rg -n 'intent-filter|android:scheme|android:host' AndroidManifest.xml - Grep the code (smali/Java/Kotlin) for dangerous sinks:
rg -n 'addJavascriptInterface|setJavaScriptEnabled|setAllowFileAccess|setAllowUniversalAccessFromFileURLs|loadUrl' rg -n 'MODE_WORLD_READABLE|MODE_WORLD_WRITEABLE|getExternalStorage|getExternalFilesDir|openFileOutput' rg -n 'getSharedPreferences|rawQuery|execSQL|PendingIntent\.(getActivity|getBroadcast|getService)' rg -n 'getIntent\(\)\.getData|getStringExtra|onNewIntent|shouldOverrideUrlLoading' - Confirm the trust crossing: is the exported component reachable from another app? Does the WebView load or bridge to a URL derived from an intent/remote page? Is the stored value sensitive (token/PII/key)?
- Check for a real control (§5): signature permission, Keystore/Encrypted*,
autoVerify+assetlinks.json, immutable PendingIntent, correct pinning. - Check network config: open
res/xml/network_security_config.xml— is cleartext permitted, or<trust-anchors>includinguserCAs (defeats pinning)? - Trace secrets: grep
res/values/strings.xml,google-services.json, andstringson the binary for API keys / Firebase URLs (cross-ref hardcoded-secrets skill for the leak itself).
7. Modern & niche variants
- Intent redirection / "intent hijacking": an exported component that extracts a
nested
Intent/URL from extras andstartActivity/startServiceon it — lets a malicious app pivot through your app's privileges into non-exported components. - Read-only ContentProvider path traversal:
openFileimplementing a file provider that resolves../in the requested path, leaking app-private files. - PendingIntent hijack: a mutable
PendingIntentwith an implicit base intent handed to another app, which fills in the blank component/action. autoVerifypresent but broken: filter declaresautoVerifybut the hosted/.well-known/assetlinks.jsonis missing/mismatched → link falls back to the chooser and any app can claim it.- WebView
file://universal access XSS→exfil: local HTML + JS bridge +setAllowUniversalAccessFromFileURLs(true)lets injected JS read arbitrary files and POST them out. - Tapjacking / overlay: sensitive screens without
filterTouchesWhenObscured/FLAG_SECURE, enabling overlay-driven clickjacking. - Task hijacking (StrandHogg): exported launcher activity with
taskAffinity/singleTaskmisconfig allowing UI spoofing. - Firebase/backend misconfig referenced in the app: world-readable Realtime DB / Storage bucket URL embedded in resources (the app is the discovery vector; the finding may become a backend HTTP issue — see §11).
8. Common false positives
exported="true"on aLAUNCHERactivity or a component gated by a genuinesignature-level permission.- WebView with JS enabled but loading only bundled
file:///android_assetcontent and noaddJavascriptInterface. getExternalStoragewrites of non-sensitive, already-public media.allowBackup/cleartext defaults on a debug-only build variant that is not shipped.- Deep links that only route to a read-only, non-privileged screen with no parameter-driven action.
9. Severity & exploitability
Base Medium–High. Critical when a WebView JS bridge or deep-link→intent
chain yields CODE_EXEC, or an exported provider/backup leaks credentials/tokens
(SECRET_LEAK) usable against the backend. Lower when the exposed data/action is
non-sensitive or the component requires a signature permission. Uplift when the
storage/JS-bridge leak feeds an account-takeover chain. Score with
references/severity-model.md.
10. Remediation
Set exported="false" unless truly needed; protect required exports with a
signature custom permission. Disable JS unless required; never
addJavascriptInterface to untrusted content; disable file-URL universal access.
Store secrets in the Android Keystore / EncryptedSharedPreferences; keep files in
MODE_PRIVATE internal storage. Use verified App Links (autoVerify +
assetlinks.json) and validate deep-link parameters. Enforce HTTPS via
network_security_config and pin certificates correctly. Use FLAG_IMMUTABLE
PendingIntents. Set allowBackup="false" and ship non-debuggable builds.
11. Output
Append each confirmed finding to findings/44-mobile-android-security.md using
references/finding-template.md. Set Class: Mobile — Android and the specific
CWE (e.g. CWE-926 exported component, CWE-919 WebView, CWE-312 cleartext storage,
CWE-749 exposed method, CWE-79 WebView XSS).
Reachable over: N/A (client/on-chain) for manifest/binary/on-device flaws.
Reproduce with device tooling, not Burp: apktool d/jadx to read the manifest and
smali; adb shell am start/am broadcast/content query to hit exported
components; a malicious PoC app + Intent/PendingIntent for intent hijacking;
adb backup to test allowBackup; Frida to hook JS bridges and pinning;
an emulator + MITM proxy to prove cleartext/pinning bypass. Exception: if the
finding is actually the backend (e.g. an open Firebase/REST endpoint the app
discloses), set Reachable over: Mobile/API and include one Burp-pasteable HTTP
request to that endpoint.
Primitives (controlled): provides SECRET_LEAK(insecure storage —
world-readable prefs, external files, backup, embedded keys), CODE_EXEC(WebView
JS bridge / deep-link→intent redirection), DATA_READ(exported provider /
component); consumes none.
References
- CWE-926, CWE-919, CWE-312, CWE-749, CWE-79; OWASP Mobile Top 10 (M1–M10) & OWASP MASVS/MASTG; Android developer security guidance (App components, WebView, Data & file storage, App Links, Network security config).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

