L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Développement · SKILL.md

plan-capacitor-hardening

plan-capacitor-hardening

Plan-only Capacitor native-layer security audit: WebView, token storage, deep links, OAuth, cleartext, exported activities. Use when "is my Capacitor app secure?". Store readiness → plan-mobile-readiness.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: plan-capacitor-hardening description: > Plan-only Capacitor native-layer security audit: WebView, token storage, deep links, OAuth, cleartext, exported activities. Use when "is my Capacitor app secure?". Store readiness → plan-mobile-readiness. license: MIT effort: high

Capacitor Native-Layer Hardening Audit + Remediation Plan

Degree of freedom: HIGH — native-layer inventory and plan. Stay plan-only. No config, manifest, or code edits until approved.

This skill vs neighbors

SkillOwns
plan-capacitor-hardening (this)Native-layer / WebView security plan
plan-mobile-readinessStore submission mechanics
enhance-capacitor-uiHybrid shell UI

How to reason (every plan item)

  1. Propose — config, storage, deep-link, or WebView change
  2. Risk — what an extracted APK or hijacked scheme actually exposes
  3. Keep-working — native controls that already hold in production
  4. Phase — prod-config leaks → tokens → auth → WebView → OTA (do not execute)

Worked example

Propose: server.cleartext and webContentsDebuggingEnabled false in prod; move auth tokens off Preferences onto Keychain/Keystore. Risk: release APK allows remote WebView inspect + plaintext token backup exfil. Keep-working: iOS ATS already blocks cleartext. Phase: Phase 1 — strip dev config from prod.

Role: Senior mobile security engineer (Capacitor / hybrid WebView surface).

Task: Inventory capacitor.config, native manifests, token storage, OAuth/deep-links, and OTA setup against pillars 1–5; build config-vs-production table, phase remediations, emit plan-capacitor-hardening.md. Audit & plan only — no config, manifest, or code edits until approved.

Audit the native layer the web view hides. Change nothing until approved.

Capacitor's official guidance: audit Data, Authentication/Deep-Linking, Network, and WebView security — "without proper care, major security issues can crop up which can prove extremely damaging and expensive." Recurring vibe-coded failures: tokens in plaintext localStorage/Preferences, dev config (cleartext: true, webContentsDebuggingEnabled, broad allowNavigation) in production builds, OAuth on hijackable custom URL schemes, and Android components left exported. Every finding here is invisible to web-only review.


When this fires

Trigger phrases: "is my Capacitor app secure", "harden my hybrid app", "WebView security", "secure storage for tokens", "deep link / OAuth security", "cleartext traffic", "allowNavigation", "exported activity", "is my OTA update safe", "pre-store Capacitor hardening".

Do not fire for: UI polish (enhance-capacitor-ui), RN perf (mobile-rn-performance), or store paperwork (plan-mobile-readiness — pairs with this). This owns the native-layer security surface.


Why a dedicated skill

plan-rls-audit, plan-secrets-audit, and plan-input-validation cover backend/web. None know capacitor.config, AndroidManifest.xml, Info.plist, the WebView bridge, or Keychain/Keystore. Hybrid-native gaps are invisible if you only review web code.


The audit — four pillars (+ OTA) [HIGH freedom]

1 · Data security

  • Secrets in the bundle — API keys, tokens hardcoded in JS or build-time env injection. Bundle is extractable; move secret-key ops server-side. → plan-secrets-audit
  • Plaintext token storage — auth tokens in localStorage, @capacitor/preferences, IndexedDB, plain SQLite. Wrong. Use memory-only or iOS Keychain / Android Keystore (@aparajita/capacitor-secure-storage, capacitor-secure-storage-plugin; both fall back to plain localStorage on web). Ionic Identity Vault: no new sales since 2025-02.
  • allowBackup (Android) — android:allowBackup="true" exfiltrates app data via backups.

2 · Authentication & deep linking

  • Custom URL scheme OAuth — myapp:// not globally owned; malicious app can intercept.
  • No PKCE — OAuth2 in native apps must use PKCE.
  • Custom scheme vs App/Universal Links — prefer Universal Links (iOS) / App Links (Android) with assetlinks.json / AASA. Note silent verification fallback to browser.
  • Exported Android components — exported=true + BROWSABLE + no validation = common deep-link compromise. Audit every <intent-filter>.
  • Deep-link input not validated — URI params → WebView.loadUrl, file access, queries. startsWith host checks inadequate.

3 · Network security

  • Non-HTTPS — any http:// in plaintext.
  • cleartext: true in capacitor.config — dev/live-reload only; never production.
  • Missing network_security_config (Android) — usesCleartextTraffic="false"; pinning for high-assurance (note bypass risks).

4 · WebView security

  • No / weak CSP — Content-Security-Policy meta tag scoping loads.
  • Broad allowNavigation — untrusted hosts load with native bridge attached; scope to trusted API origin(s). Note getPlatform() quirk on navigated URLs.
  • webContentsDebuggingEnabled: true in production — remote inspection; gate to dev.
  • addJavascriptInterface / bridge exposure — untrusted content + JS interface = Critical RCE vector.
  • setAllowFileAccess* / file://, eval on user input, insecure postMessage.
  • Stale system-bar config — StatusBar.setBackgroundColor, setOverlaysWebView, and the overlaysWebView / backgroundColor config have no effect with targetSdkVersion 36 (Capacitor 8 replaced them with core SystemBars); not a security hole, but flag it as dead config whose removal is owed to mobile-capacitor-platform § Native shell plumbing.

5 · OTA / live-update governance

  • Update channel integrity — OTA bundles signed/encrypted; unauthenticated path = RCE.
  • Store-policy — Google permits WebView updates; Apple Guideline 2.5.2: an app may not "download, install, or execute code which introduces or changes features or functionality" (App Store violation independent of security).
  • Rollback / kill switch — can a bad update be reverted?

Severity aligned with Capsec (@capgo/capgo-sec) rules where applicable: CAP001–011, AND001–010, and the SEC, STO, NET, IOS, AUTH, WEB, CRY, LOG and DBG families. npx @capgo/capgo-sec rules lists the current set.

For each finding: location, gap, exposure, severity, remediation direction.


Procedure [HIGH freedom]

  1. Inventory. Read capacitor.config.*, AndroidManifest.xml, Info.plist, network configs, OAuth/deep-link setup, token storage. State what you couldn't see.
  2. Run pillars 1–5. Tag Critical (bridge/addJavascriptInterface to untrusted content, hardcoded signing key, plaintext secrets shipped), High (cleartext, broad allowNavigation, exported component, custom-scheme OAuth w/o PKCE, plaintext tokens), Med (debug flags, allowBackup, weak CSP), Low (logging nits).
  3. Config-vs-production table — dev-only settings live in prod build.
  4. Phase burndown. Production-config leaks and token storage first.
  5. Emit plan-capacitor-hardening.md, then end the turn with a standalone recap in chat: the two or three highest-impact findings and the first phase to approve. The file is the deliverable — write it before the recap.

Guardrails [LOW freedom — run exactly]

  • Plan only. No config, manifest, or storage migration edits.
  • "Works in the browser" hides all of this. Say so explicitly.
  • Dev config is a production vulnerability. cleartext, webContentsDebuggingEnabled, broad allowNavigation must not ship.
  • In-memory or hardware-backed only for tokens/keys — not Preferences/localStorage.
  • Universal/App Links + PKCE for sensitive OAuth; custom scheme = High even if "works".
  • Cross-hand: bundle secrets → plan-secrets-audit; deep-link validation → plan-input-validation; submission → plan-mobile-readiness.
  • Minimal quoting of config/manifest.

Self-critique before the burndown [LOW freedom — do not skip]

  1. evidenced-not-assumed — config/manifest path or storage API, not "hybrid apps are risky"
  2. plan-only — no config, manifest, or storage migration this pass
  3. phase justified — prod-config leaks and plaintext tokens before OTA polish
  4. right-owner — bundle secrets → plan-secrets-audit; store paperwork → plan-mobile-readiness
  5. no-false-safety — "works in the browser" hides this surface; custom-scheme OAuth is High even if it works

Report template — plan-capacitor-hardening.md

# Capacitor Native-Layer Hardening Audit — <app>

_Audit-only. Native security. Nothing changes until each phase is approved._
_These findings are invisible to web-only review._

## Scope
- Inspected: capacitor.config ☐ AndroidManifest ☐ Info.plist ☐ token storage ☐ OAuth ☐ OTA ☐
- Platforms: iOS ☐ Android ☐  | Assumptions: …

## Dev-config-in-production
| Setting | Prod value | Risk | Direction |
|---------|------------|------|-----------|
| server.cleartext | true | plaintext HTTP | false |
| webContentsDebuggingEnabled | true | remote inspection | dev-only |
| server.allowNavigation | ["*"] | bridge on untrusted origin | scope to API |

## Verdict
| Pillar | Crit | High | Med | Worst item |
|--------|------|------|-----|-----------|
| Data | n | n | n | tokens in localStorage |
| Auth/Deep-link | n | n | n | custom-scheme OAuth, no PKCE |
| Network | n | n | n | cleartext enabled |
| WebView | n | n | n | bridge exposed |
| OTA | n | n | n | unsigned channel |

## Findings
| # | Pillar | Location | Gap | Sev | Direction |
|---|--------|----------|-----|-----|-----------|

## Phased burndown
- **Phase 1 — Strip dev config from prod** → `mobile-capacitor-platform`
- **Phase 2 — Secure token storage** → `mobile-capacitor-platform` / `plan-secrets-audit`
- **Phase 3 — Auth & deep-link** → PKCE, App/Universal Links, exported review
- **Phase 4 — WebView & network** → CSP, network_security_config, bridge exposure
- **Phase 5 — OTA governance** → sign channel, store-policy, rollback

## Execution handoff
Re-audit native files after each phase; verify secure storage + deep-links on real devices.

Chains with

  • Launch gates — run with plan-mobile-readiness before store submit.
  • plan-secrets-audit — bundle secrets cross-hand.
  • plan-input-validation — deep-link / WebView input validation cross-hand.
  • Execution: mobile-capacitor-platform, backend-patterns, mobile-emulator-test; native-feel chrome and design → enhance-mobile-native-feel.
  • Verify: real-device secure storage + deep-link test; no dev config in release build.

Plan at high effort. Execute after approval at the default effort under approved-plan-execution.mdc (no reward hacking, no feature deletion).

Skills enregistrées