Android code auditor
Skill calvin-iyer/android-skills/plugins/android-skills/skills/android-code-auditor
Performs a thorough code audit of an Android project across four domains: Security, Performance, Architecture, and Dependencies. Combines deep codebase analysis with live web research on the libraries and technologies actually found in the project, then produces a severity-ranked status-tracked `code-audit.md` file (CRITICAL / HIGH / MEDIUM / LOW severity, PENDING / DONE / SKIPPED / CANCELLED status per item). USE THIS SKILL whenever the user says "code audit", "audit my code", "audit the codebase", "security audit", "performance audit", "architecture review", "dependency audit", "review my Android code", "check my code for issues", "find security issues", "find performance issues", "find memory leaks", "check for vulnerabilities", "is my code secure", "audit dependencies", "walk through the audit", "update the audit", "recreate the audit", "show audit summary", or asks about an existing `code-audit.md` file. Exit early if the working directory is not an Android project.From its SKILL.md
npx -y skills add calvin-iyer/android-skills --skill android-code-auditorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
19.8 KB, ~4.6k tokens by cl100k_base, as published. Nobody here has run it
Android Code Auditor
Audit an Android project for Security, Performance, Architecture, and Dependency issues using deep codebase analysis and live web research. Produce and maintain a severity-ranked code-audit.md file.
Modes
Detect which mode the user wants from their message:
- Generate - first-time creation of
code-audit.md(default if file does not exist). - Recreate - user says "recreate", "redo", "fresh audit". Disposes existing file, starts clean.
- Update - user says "update audit", "refresh audit". Re-runs analysis, preserves DONE/SKIPPED/CANCELLED.
- Walkthrough - user says "walk me through", "go through issues", "next issue". One item at a time by severity.
- Check issue - user says "explain C2", "show me H4", "what's wrong with M1". Deep-dive one item.
- Update status - user says "mark X done", "skip Y", "cancel Z". Edit statuses in place.
- Summary - user says "what's left", "audit status", "show summary". Fast read-only.
If mode is ambiguous, ask the user. Do not guess.
Step 0: Android project detection
Before any other action, verify this is an Android project. Check for ANY of:
android/directory at repo rootapp/build.gradleorapp/build.gradle.ktsAndroidManifest.xmlanywhere in treepubspec.yamlwith Flutter declaration ANDandroid/subdirectory- Unity:
ProjectSettings/directory with Android build target markers - React Native:
android/build.gradle - Capacitor:
capacitor.config.*referencing android platform
If NONE match, stop immediately:
Not an Android project.
android-code-auditoronly runs on Android apps and games. Detected: [briefly describe what kind of project it appears to be, or "no recognizable project structure"]. Addforceto your message to override.
If the user included "force" in their message, skip this check and proceed.
Mode 1: Generate
Step 1: Check for existing file
If code-audit.md already exists at repo root:
"A
code-audit.mdalready exists. Do you want to recreate it from scratch (discards all statuses) or update it (re-runs analysis, preserves your progress)?"
If Recreate chosen: delete the file, continue with Step 2. If Update chosen: switch to Mode 3 (Update).
Step 2: Ask analysis mode
Ask the user:
"Run the audit with parallel agents (4 domains analysed simultaneously - faster, higher token cost) or sequential (one domain at a time - slower, lower token cost)?"
If the user already indicated a preference in their invocation message, skip asking. Default to parallel if unspecified.
Step 3: Stack detection
Do a fast stack detection pass. If the code-review-graph MCP is available, use get_architecture_overview_tool first for a structural map. Otherwise use Grep/Read/Glob.
Read the following files (whichever exist):
app/build.gradleand/orapp/build.gradle.ktsgradle/libs.versions.tomlorlibs.versions.tomlpubspec.yamlpackage.jsonapp/src/main/AndroidManifest.xmlorAndroidManifest.xmlsettings.gradleorsettings.gradle.kts
Extract and record:
- Project name (from
applicationIdor app name) - Stack: Native Kotlin/Java | Flutter | React Native | Unity | Capacitor (or combination)
- UI layer: Jetpack Compose | Views/Fragments | mixed
- DI: Hilt | Koin | manual | none
- Networking: Retrofit | Ktor | OkHttp | Volley | none
- Storage: Room | SQLDelight | DataStore | SharedPreferences | Realm
- Firebase products present (Auth, Firestore, RTDB, Storage, Analytics, Crashlytics, FCM, App Check, AdMob)
- IAP: Play Billing Library | RevenueCat | none
- Image loading: Coil | Glide | Picasso | none
- All declared dependency coordinates and versions
minSdk,targetSdk,compileSdk- AGP version, Kotlin version, Gradle wrapper version
- Compose BOM version (if used)
Pass this stack summary to every domain agent.
Step 4: Spawn domain agents
Spawn 4 agents - one per domain: Security, Performance, Architecture, Dependencies.
Parallel: spawn all 4 in a single message (all Agent tool calls in one response). Sequential: spawn Security, wait for result, then Performance, wait, then Architecture, wait, then Dependencies.
Each agent receives this prompt (fill in {{placeholders}}):
You are performing a {{domain}} audit of an Android project. Every finding must be grounded in code you actually read from the repo or a URL you actually fetched this session. No assumptions. No training-data citations.
## Project context
Working directory: {{cwd}}
Project name: {{project_name}}
Stack: {{stack_summary}}
minSdk: {{minSdk}} | targetSdk: {{targetSdk}} | compileSdk: {{compileSdk}}
## Code-review-graph MCP
If the code-review-graph MCP server is available in your tools, use these tools:
- get_architecture_overview_tool - structural map of whole project
- semantic_search_nodes_tool - semantic search across all symbols
- query_graph_tool - query relationships between components
Fall back to Grep, Read, and Glob if the MCP is not available.
## Your domain: {{domain}}
{{domain_specific_instructions}}
## Output format
For each issue, return exactly:
ISSUE:
- Domain: {{domain}}
- Severity: critical | high | medium | low
- Title: <max 60 chars>
- Where: <exact file path and line number>
- What: <one sentence describing the problem>
- Why: <concrete impact if not fixed>
- How to fix: <concrete steps with corrected code snippet where applicable>
- Reference: <URL actually fetched this session>
If zero issues found in your domain:
NO_ISSUES: {{domain}}
Security agent - domain_specific_instructions value:
Phase 1 - Codebase scan:
1. Hardcoded secrets: grep source files (exclude test/) for: apiKey, api_key, password, passwd, secret, token, private_key, client_secret, AUTH_, KEY_, PASSWORD. Read each match to confirm it is a real secret value, not just a variable name.
2. Exported components: read AndroidManifest.xml. For every component with android:exported="true", check whether android:permission is set. Flag unprotected exported Activities, Services, BroadcastReceivers, ContentProviders.
3. Insecure network config: check res/xml/network_security_config.xml for cleartextTrafficPermitted="true". Grep source for plain http:// base URL strings. Check manifest for android:usesCleartextTraffic="true".
4. WebView misuse: grep for setJavaScriptEnabled, addJavascriptInterface, setAllowFileAccess, setAllowUniversalAccessFromFileURLs. Read each call site to check if guarded.
5. Deeplink security: find intent filters with android:scheme in manifest. Check android:autoVerify="true" for App Links. Grep for deeplink parameter handling - flag params used directly in SQL, file paths, or network calls without validation.
6. Permissions: list all <uses-permission> entries. Flag RECORD_AUDIO, READ_CONTACTS, READ_CALL_LOG, ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, CAMERA where no corresponding use is found in source.
7. Key storage: grep for SharedPreferences storing values that look like tokens or credentials. Check whether EncryptedSharedPreferences or Android Keystore is used for sensitive data.
8. Biometric: grep for BiometricManager, BiometricPrompt. Flag setAllowedAuthenticators(BIOMETRIC_WEAK) where strong auth is required.
9. Weak crypto: grep for MD5, SHA1, DES, RC4, "ECB" mode usage.
Phase 2 - Web research:
- Fetch https://developer.android.com/privacy-and-security/security-tips
- Search for CVEs for any security-relevant libraries at their declared versions
- Fetch current OWASP Mobile Top 10 and note which items apply
Performance agent - domain_specific_instructions value:
Phase 1 - Codebase scan:
1. Main thread I/O: grep for File(, openFileOutput, openFileInput, getSharedPreferences, SharedPreferences.Editor usage - check each is wrapped in withContext(Dispatchers.IO) or a background thread.
2. Main thread network: grep for Retrofit/OkHttp/Ktor call sites not inside suspend functions or withContext(Dispatchers.IO).
3. Memory leaks:
- Grep for companion object or top-level val/var holding Context, Activity, Fragment, View, or ViewBinding references.
- Grep for anonymous listener registrations stored as fields but not cleared in onDestroy/onDestroyView.
- Grep for Fragment ViewBinding - verify binding is nulled in onDestroyView.
4. Compose recomposition (only if Compose in stack):
- Grep for lambda expressions passed as Composable params not wrapped in remember.
- Grep for data class types used as Composable params - check @Stable or @Immutable annotation.
- Grep for .filter, .map, .sorted, .groupBy inside @Composable bodies not wrapped in remember or derivedStateOf.
- Grep for expensive computations inside @Composable bodies not memoised.
5. Application.onCreate: read Application class(es). Flag synchronous disk reads, network calls, or heavy init chains.
6. GlobalScope: grep for GlobalScope.launch, GlobalScope.async.
7. runBlocking: grep for runBlocking outside test directories.
8. Large assets: list files in res/drawable*, res/raw, assets/. Flag PNG files over 100KB.
Phase 2 - Web research:
- Fetch https://developer.android.com/topic/performance/vitals
- If Compose in stack: fetch https://developer.android.com/develop/ui/compose/performance
- Search for current Baseline Profiles guidance
- Check App Startup library guidance if heavy Application.onCreate found
Architecture agent - domain_specific_instructions value:
Phase 1 - Codebase scan:
1. ViewModel-View coupling: grep ViewModel files for Activity, Fragment, View, Context type references. Read matches to confirm if ViewModel holds a View reference.
2. Missing repository layer: grep Activity and Fragment files for direct DAO, Retrofit service, or database calls. These should go through a Repository.
3. God classes: list all Kotlin/Java source files over 400 lines. Read each and describe what responsibilities it handles. Flag if multiple unrelated concerns are present.
4. Coroutine scopes: grep for CoroutineScope( - check each is tied to a lifecycle or has SupervisorJob + cancellation. Grep for viewModelScope usage to confirm ViewModels use it. Flag manual Job() without SupervisorJob in custom scopes.
5. SavedStateHandle: grep ViewModel files for state that must survive process death (user input, selected IDs, scroll position) but does not use SavedStateHandle.
6. DI consistency: determine DI approach (Hilt / Koin / manual). Flag classes constructing their own dependencies with = SomeClass() instead of receiving them via injection.
7. NavController vs manual back stack: if NavGraph is declared, grep for supportFragmentManager.beginTransaction and supportFragmentManager.popBackStack as inconsistency signals.
8. State in Composables: grep for remember { mutableStateOf } inside Composables holding business state (loaded data, selected item, form values) that should be in ViewModel.
Phase 2 - Web research:
- Fetch https://developer.android.com/topic/architecture
- If Compose in stack: fetch https://developer.android.com/develop/ui/compose/architecture
- Search current community guidance on Hilt vs Koin for Android 2025/2026
- Fetch https://developer.android.com/modern-android-development for MAD scorecard criteria
Dependencies agent - domain_specific_instructions value:
Phase 1 - Codebase scan:
Read all dependency declarations from:
- app/build.gradle and/or app/build.gradle.kts
- Root build.gradle / build.gradle.kts
- gradle/libs.versions.toml or libs.versions.toml (if present)
- Any module-level build.gradle* files
Record every implementation, api, kapt, ksp, annotationProcessor, testImplementation, androidTestImplementation coordinate with its full group:artifact:version.
Note any force version resolution, resolutionStrategy, or exclude directives.
Phase 2 - Web research (fetch live, not from training data):
1. Android Gradle Plugin: fetch https://developer.android.com/build/releases/gradle-plugin - current stable version.
2. Kotlin: fetch https://kotlinlang.org/docs/releases.html - current stable version.
3. Compose BOM: fetch https://developer.android.com/develop/ui/compose/bom/bom-mapping - current stable BOM.
4. AndroidX: for each detected androidx.* group, check https://developer.android.com/jetpack/androidx/versions.
5. Firebase BoM: fetch https://firebase.google.com/support/release-notes/android - current BoM version.
6. Play Billing: fetch https://developer.android.com/google/play/billing/release-notes - current minimum required version.
7. CVEs: for each third-party library (non-Google, non-AndroidX), search osv.dev for known vulnerabilities at the declared version. Query format: "site:osv.dev <group-id>".
8. Deprecated Gradle configurations: flag any compile, provided, or apk configuration usage.
Flag every dependency that is:
- More than 2 minor versions behind current stable
- Has a known CVE at the declared version
- Uses a deprecated Gradle configuration
- Incompatible with the declared AGP/Kotlin/Gradle version
Step 5: Consolidate and deduplicate
After all agents complete:
- Merge all ISSUE blocks into one list.
- Deduplicate: if two agents flagged the same file and line for overlapping reasons, merge into one issue - keep the higher severity, combine descriptions.
- Sort: CRITICAL, HIGH, MEDIUM, LOW. Within each tier: Security, Performance, Architecture, Dependencies.
- Assign stable IDs: C1, C2, ... H1, H2, ... M1, M2, ... L1, L2, ...
Step 6: Write code-audit.md
Write to repo root:
# Code Audit
**Created:** YYYY-MM-DD HH:MM (timezone)
**Last updated:** YYYY-MM-DD HH:MM (timezone)
**Project:** <project name>
**Stack:** <e.g. Native Kotlin + Hilt + Compose + Firebase>
## Summary
| Severity | Total | PENDING | DONE | SKIPPED | CANCELLED |
|---|---|---|---|---|---|
| CRITICAL | N | N | N | N | N |
| HIGH | N | N | N | N | N |
| MEDIUM | N | N | N | N | N |
| LOW | N | N | N | N | N |
**Top blockers (CRITICAL, PENDING):**
- [ ] C1. <title>
- [ ] C2. <title>
## CRITICAL
### [PENDING] C1. <Short title>
**Domain:** Security
**What:** <one-sentence description>
**Why critical:** <concrete impact>
**Where:** `path/to/File.kt:42`
**How to fix:** <concrete steps with corrected code snippet>
**Reference:** <URL fetched this session>
## HIGH
### [PENDING] H1. ...
## MEDIUM
### [PENDING] M1. ...
## LOW
### [PENDING] L1. ...
---
_CRITICAL: exploitable vulnerability or data loss risk. HIGH: serious quality or security issue. MEDIUM: best-practice violation. LOW: minor improvement._
## Change log
- YYYY-MM-DD HH:MM - Created
Step 7: Report summary
After writing the file, output to user:
- Total count per severity
- Top 3 CRITICAL items (if any)
- Offer: "Want me to walk through these one at a time, or jump to a specific issue by ID (e.g. C1, H3)?"
Mode 2: Recreate
- Delete
code-audit.md. - Ask analysis mode (Step 2 of Mode 1).
- Run Mode 1 Steps 3-7 (stack detection, agent spawning, consolidation, write file, report).
Mode 3: Update
- Read
code-audit.md. Record every item ID and current status. - Ask analysis mode (Step 2 from Mode 1). Skip if user already indicated preference.
- Run Mode 1 Steps 3-5 (stack detection + domain agents + consolidation).
- Diff new findings against captured statuses:
- Item still present AND was DONE/SKIPPED/CANCELLED: preserve that status
- Item still present AND was PENDING: keep PENDING
- New item: PENDING
- Old item no longer detected: remove from file, note in changelog
- Re-assign IDs from scratch in new severity order.
- Rewrite
code-audit.md. - Update
Last updated. Append changelog entry: "Re-analysed - N new issues, N resolved, N statuses preserved." - If any carried-over items received new IDs (because severity order changed), report the mapping to the user: "Note: some item IDs changed due to re-ordering. Former C1 is now H2." Then report what changed overall.
- Report what changed.
Mode 4: Walkthrough
Present one PENDING item at a time: CRITICAL, HIGH, MEDIUM, LOW order. Within each tier, numeric order.
For each PENDING item:
- Show: title, domain, what, why, where, how to fix, reference URL.
- Wait for user response:
- "done" / "fixed" / "did it" - mark DONE, move to next
- "skip" - mark SKIPPED, move to next
- "cancel" - mark CANCELLED, move to next
- "later" / "pause" / "stop" - stop walkthrough, no status change
- question - answer it, then re-prompt for status
- After each status update: edit
code-audit.mdimmediately. Update the status bracket in the issue heading. Recompute all status-column counts in the Summary table for the affected severity row. Append changelog entry. - Announce tier transitions: "All CRITICAL items handled. Moving to HIGH."
Skip items already DONE/SKIPPED/CANCELLED.
When all items are handled or user pauses: report progress (X done, Y skipped, Z cancelled, W pending).
Mode 5: Check issue
User says "explain C2", "show me H4", "what's wrong with M1":
- Read
code-audit.md. - Find the item by ID.
- Read the source file at the path in the
Wherefield. - Output:
- Full item entry from the file
- The actual bad code (quoted lines from the source file)
- A corrected version of those lines
- Deeper explanation: concrete scenario of how this causes a security breach, crash, performance problem, or maintenance issue in their specific codebase
Do not run new analysis or web research. Read the audit file and referenced source file only.
Mode 6: Update status
User says "mark C1 done", "skip H2 and H3", "cancel M4":
- Parse all IDs from the message.
- Update each item's status bracket in
code-audit.md. - Recalculate and update Summary table counts.
- Append one changelog entry per change.
- Confirm to user: e.g. "Marked C1 DONE, H2 SKIPPED, H3 SKIPPED."
Mode 7: Summary
Read code-audit.md. Output:
- The full Summary table
- All PENDING items grouped by severity (ID + title, one line each)
No analysis. No web research. No file writes.
Quality bar
- Every issue must cite exact file path and line number. "Insecure WebView config" is not acceptable; "
app/src/main/java/com/example/WebActivity.kt:87-setJavaScriptEnabled(true)with no origin restriction" is acceptable. - Every issue must include a reference URL from live web research conducted this session.
- Never invent issues not present in the code.
- Never omit issues because they seem minor - severity ranking communicates priority.
- Web research must be live (WebSearch + WebFetch). Library versions and CVE databases change.
Things to avoid
- Do not write
code-audit.mdbefore both codebase scan and web research are complete. - Do not include issues from domains that do not apply (e.g., no Compose recomposition issues if the project uses Views only).
- Do not use em dashes anywhere in the output file or in responses.
- Do not lose user-set statuses during Update mode.
- Do not silently overwrite the file - always append to the change log.
- Do not make assumptions. Every finding must come from (a) code actually read from this repo, or (b) a URL fetched this session.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.