| name | rn-security-audit |
| description | Audit Expo React Native apps for mobile-specific security issues — JS bundle secret leakage, insecure storage of tokens, unvalidated deep links, WebView misconfiguration, over-broad native permissions, and OWASP MASVS gaps. Apply ONLY when the task explicitly asks for a security review, threat model, store-submission security check, or remediation of a known mobile vulnerability. Do NOT apply for general code review, performance work, or routine feature work. |
| metadata | {"owner":"rn-builder","status":"stable"} |
rn-security-audit
Purpose
Mobile-specific security checks for an Expo React Native app. Covers the attack surface that web-focused security tools miss: the JS bundle shipped inside the IPA/AAB, key/token storage on device, deep link entry points, WebView injection, and native permission scope.
This skill is defensive only. It surfaces issues and prescribes fixes. It does not generate exploit code, payloads, or evasion techniques.
When to Apply
Use this skill ONLY when one of these triggers is present:
- User asks for a "security audit", "security review", "threat model", or "pen test prep" of the app
- User is preparing for App Store / Play Store submission and wants a pre-submission security check
- User reports a specific mobile security concern (leaked key, insecure storage, deep link hijack, WebView XSS)
- User is responding to a vendor security questionnaire, SOC 2 / ISO control evidence request, or app store security rejection
- A new dependency, native module, or auth flow is being added and the user explicitly asks "is this safe?"
Do NOT use this skill when:
- The task is a generic code review → use the
code-review skill or the Code Reviewer agent.
- The task is performance, jank, or bundle size → use
react-native-best-practices.
- The task is a backend / API security question → hand off to the Security Engineer agent.
- The task is smart contracts or web3 → hand off to Blockchain Security Auditor.
- The task is dependency CVEs / outdated packages → read
../rn-dependency-audit/SKILL.md.
Threat Model Boundaries
This skill assumes:
- Trusted: the EAS build pipeline, the project's own backend,
expo-secure-store.
- Untrusted: anything in the JS bundle (it ships in cleartext inside the IPA/AAB and can be extracted), deep link URLs, WebView content, third-party SDKs, and the device itself on jailbroken/rooted phones.
A "secret" embedded in the JS bundle is not a secret. Even Hermes bytecode is trivially reversed. Treat every process.env.EXPO_PUBLIC_* value, every config plugin string, and every literal in the source tree as public.
Problem → Reference
Default Audit Order
When the user asks for a general "security audit" with no specific focus, run the checks in this order — cheapest first, blast radius highest first:
- Read
SECURITY.md if present — load existing Accepted Risks, Known Non-Issues, and Suppressed CVEs so the audit doesn't re-flag already-decided findings. If absent and this is a serious audit, propose writing one from security-md-template.md.
- Bundle secret scan — fastest signal, hardest to fix retroactively (rotate the key).
- Storage audit — wrong place for tokens is the #2 mobile finding.
- Permissions audit — over-broad permissions get apps rejected from stores.
- Deep links — only if the app declares any URL scheme or universal link.
- WebView — only if
react-native-webview is in package.json.
- MASVS checklist — pre-submission only.
- Update
SECURITY.md with any newly accepted risks or new suppressions surfaced by this audit (user approval required per entry).
Stop after each step and report findings before moving on. Do not silently roll fixes — the user must approve every change.
Reporting Format
Every finding produced by this skill must follow this structure so it can be triaged:
Finding: <one-line title>
Severity: Critical | High | Medium | Low | Info
Location: <file:line or "configuration" or "build output">
Evidence: <exact snippet, output line, or config value>
Impact: <what an attacker gains>
Fix: <concrete change, with file:line where the fix lands>
Verification: <command or manual step that confirms the fix>
Severity rubric:
- Critical: secret in shipped bundle, auth bypass, RCE.
- High: PII in plaintext storage, deep link → privileged action without confirmation, WebView with
originWhitelist=['*'].
- Medium: over-broad permissions, missing cert pinning when handling financial / health data, debug logging of sensitive fields.
- Low: missing jailbreak/root detection on apps without high-value data, weak but non-exploitable patterns.
- Info: best-practice gaps with no immediate exploit path.
What This Skill Does NOT Cover
- Backend / API security — that is the Security Engineer agent's job.
- Network attack surface beyond the mobile client — TLS termination, WAF, etc.
- Compliance frameworks themselves (HIPAA, PCI, SOC 2) — hand off to Compliance Auditor.
- iOS/Android OS hardening for jailbroken/rooted devices in adversarial deployments — that is a specialized native engagement.
- Source-level cryptography review — if the app implements its own crypto, that is a red flag in itself; route to Security Engineer.
Verification
A security audit is complete when:
- Every check listed in the relevant reference file has been run (or explicitly skipped with a reason).
- Every finding is recorded in the reporting format above.
- Critical and High findings either have a merged fix or an explicit user acknowledgement to ship with the risk.
- The user has a written summary they can attach to a security questionnaire or store submission.
A clean run (no findings) is reported as such — do not invent findings to look thorough.