--- name: capacitor-security description: Comprehensive security guide for Capacitor apps using Capsec scanner. Covers 63+ security rules across secrets, storage, network, authentication, cryptography, and platform-specific vulnerabilities. Use this skill when users need to secure their mobile app or run security audits. --- # Capacitor Security with Capsec Zero-config security scanning for Capacitor and Ionic apps. ## When to Use This Skill - User wants to secure their app - User asks about security vulnerabilities - User needs to run security audit - User has hardcoded secrets - User needs CI/CD security scanning - User asks about OWASP mobile security ## Quick Start with Capsec ### Run Security Scan ```bash # Scan current directory (no installation needed) bunx capsec scan # Scan specific path bunx capsec scan ./my-app # CI mode (exit code 1 on high/critical issues) bunx capsec scan --ci ``` ### Output Formats ```bash # CLI output (default) bunx capsec scan # JSON report bunx capsec scan --output json --output-file report.json # HTML report bunx capsec scan --output html --output-file security-report.html ``` ### Filtering ```bash # Only critical and high severity bunx capsec scan --severity high # Specific categories bunx capsec scan --categories secrets,network,storage # Exclude test files bunx capsec scan --exclude "**/test/**,**/*.spec.ts" ``` ## Security Rules Reference ### Secrets Detection (SEC) | Rule | Severity | Description | |------|----------|-------------| | SEC001 | Critical | Hardcoded API Keys & Secrets | | SEC002 | High | Exposed .env File | **What Capsec Detects**: - AWS Access Keys - Google API Keys - Firebase Keys - Stripe Keys - GitHub Tokens - JWT Secrets - Database Credentials - 30+ secret patterns **Fix Example**: ```typescript // BAD - Hardcoded API key const API_KEY = 'sk_live_abc123xyz'; // GOOD - Use environment variables import { Env } from '@capgo/capacitor-env'; const API_KEY = await Env.get({ key: 'API_KEY' }); ``` ### Storage Security (STO) | Rule | Severity | Description | |------|----------|-------------| | STO001 | High | Unencrypted Sensitive Data in Preferences | | STO002 | High | localStorage Usage for Sensitive Data | | STO003 | Medium | SQLite Database Without Encryption | | STO004 | Medium | Filesystem Storage of Sensitive Data | | STO005 | Low | Insecure Data Caching | | STO006 | High | Keychain/Keystore Not Used for Credentials | **Fix Example**: ```typescript // BAD - Plain preferences for tokens import { Preferences } from '@capacitor/preferences'; await Preferences.set({ key: 'auth_token', value: token }); // GOOD - Use secure storage import { NativeBiometric } from '@capgo/capacitor-native-biometric'; await NativeBiometric.setCredentials({ username: email, password: token, server: 'api.myapp.com', }); ``` ### Network Security (NET) | Rule | Severity | Description | |------|----------|-------------| | NET001 | Critical | HTTP Cleartext Traffic | | NET002 | High | SSL/TLS Certificate Pinning Missing | | NET003 | High | Capacitor Server Cleartext Enabled | | NET004 | Medium | Insecure WebSocket Connection | | NET005 | Medium | CORS Wildcard Configuration | | NET006 | Medium | Insecure Deep Link Validation | | NET007 | Low | Capacitor HTTP Plugin Misuse | | NET008 | High | Sensitive Data in URL Parameters | **Fix Example**: ```typescript // BAD - HTTP in production const config: CapacitorConfig = { server: { cleartext: true, // Never in production! }, }; // GOOD - HTTPS only const config: CapacitorConfig = { server: { cleartext: false, // Only allow specific domains allowNavigation: ['https://api.myapp.com'], }, }; ``` ### Capacitor-Specific (CAP) | Rule | Severity | Description | |------|----------|-------------| | CAP001 | High | WebView Debug Mode Enabled | | CAP002 | Medium | Insecure Plugin Configuration | | CAP003 | Low | Verbose Logging in Production | | CAP004 | High | Insecure allowNavigation | | CAP005 | Critical | Native Bridge Exposure | | CAP006 | Critical | Eval Usage with User Input | | CAP007 | Medium | Missing Root/Jailbreak Detection | | CAP008 | Low | Insecure Plugin Import | | CAP009 | Medium | Live Update Security | | CAP010 | High | Insecure postMessage Handler | **Fix Example**: ```typescript // BAD - Debug mode in production const config: CapacitorConfig = { ios: { webContentsDebuggingEnabled: true, // Remove in production! }, android: { webContentsDebuggingEnabled: true, // Remove in production! }, }; // GOOD - Only in development const config: CapacitorConfig = { ios: { webContentsDebuggingEnabled: process.env.NODE_ENV === 'development', }, }; ``` ### Android Security (AND) | Rule | Severity | Description | |------|----------|-------------| | AND001 | High | Android Cleartext Traffic Allowed | | AND002 | Medium | Android Debug Mode Enabled | | AND003 | Medium | Insecure Android Permissions | | AND004 | Low | Android Backup Allowed | | AND005 | High | Exported Components Without Permission | | AND006 | Medium | WebView JavaScript Enabled Without Safeguards | | AND007 | Critical | Insecure WebView addJavascriptInterface | | AND008 | Critical | Hardcoded Signing Key | **Fix AndroidManifest.xml**: ```xml ``` **network_security_config.xml**: ```xml api.myapp.com your-pin-hash ``` ### iOS Security (IOS) | Rule | Severity | Description | |------|----------|-------------| | IOS001 | High | App Transport Security Disabled | | IOS002 | Medium | Insecure Keychain Access | | IOS003 | Medium | URL Scheme Without Validation | | IOS004 | Low | iOS Pasteboard Sensitive Data | | IOS005 | Medium | Insecure iOS Entitlements | | IOS006 | Low | Background App Refresh Data Exposure | | IOS007 | Medium | Missing iOS Jailbreak Detection | | IOS008 | Low | Screenshots Not Disabled for Sensitive Screens | **Fix Info.plist**: ```xml NSAppTransportSecurity NSAllowsArbitraryLoads NSAppTransportSecurity NSExceptionDomains legacy-api.example.com NSExceptionAllowsInsecureHTTPLoads NSExceptionMinimumTLSVersion TLSv1.2 ``` ### Authentication (AUTH) | Rule | Severity | Description | |------|----------|-------------| | AUTH001 | Critical | Weak JWT Validation | | AUTH002 | High | Insecure Biometric Implementation | | AUTH003 | High | Weak Random Number Generation | | AUTH004 | Medium | Missing Session Timeout | | AUTH005 | High | OAuth State Parameter Missing | | AUTH006 | Critical | Hardcoded Credentials in Auth | **Fix Example**: ```typescript // BAD - No JWT validation const decoded = jwt.decode(token); // GOOD - Verify JWT signature const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'], issuer: 'https://auth.myapp.com', audience: 'myapp', }); ``` ### WebView Security (WEB) | Rule | Severity | Description | |------|----------|-------------| | WEB001 | Critical | WebView JavaScript Injection | | WEB002 | Medium | Unsafe iframe Configuration | | WEB003 | Medium | External Script Loading | | WEB004 | Medium | Content Security Policy Missing | | WEB005 | Low | Target _blank Without noopener | **Fix - Add CSP**: ```html ``` ### Cryptography (CRY) | Rule | Severity | Description | |------|----------|-------------| | CRY001 | Critical | Weak Cryptographic Algorithm | | CRY002 | Critical | Hardcoded Encryption Key | | CRY003 | High | Insecure Random IV Generation | | CRY004 | High | Weak Password Hashing | **Fix Example**: ```typescript // BAD - Weak algorithm const encrypted = CryptoJS.DES.encrypt(data, key); // GOOD - Strong algorithm const encrypted = CryptoJS.AES.encrypt(data, key, { mode: CryptoJS.mode.GCM, padding: CryptoJS.pad.Pkcs7, }); // BAD - Hardcoded key const key = 'my-secret-key-123'; // GOOD - Derived key const key = await crypto.subtle.deriveKey( { name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' }, baseKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'] ); ``` ### Logging (LOG) | Rule | Severity | Description | |------|----------|-------------| | LOG001 | High | Sensitive Data in Console Logs | | LOG002 | Low | Console Logs in Production | **Fix Example**: ```typescript // BAD - Logging sensitive data console.log('User password:', password); console.log('Token:', authToken); // GOOD - Redact sensitive data console.log('User authenticated:', userId); // Use conditional logging if (process.env.NODE_ENV === 'development') { console.debug('Debug info:', data); } ``` ## CI/CD Integration ### GitHub Actions ```yaml name: Security Scan on: [push, pull_request] jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Run Capsec Security Scan run: bunx capsec scan --ci --output json --output-file security-report.json - name: Upload Security Report uses: actions/upload-artifact@v4 if: always() with: name: security-report path: security-report.json ``` ### GitLab CI ```yaml security-scan: image: oven/bun:latest script: - bunx capsec scan --ci artifacts: reports: security: security-report.json only: - merge_requests - main ``` ## Configuration ### capsec.config.json ```json { "exclude": [ "**/node_modules/**", "**/dist/**", "**/*.test.ts", "**/*.spec.ts" ], "severity": "low", "categories": [], "rules": { "LOG002": { "enabled": false }, "SEC001": { "severity": "critical" } } } ``` ### Initialize Config ```bash bunx capsec init ``` ## Root/Jailbreak Detection ```typescript import { IsRoot } from '@capgo/capacitor-is-root'; async function checkDeviceSecurity() { const { isRooted } = await IsRoot.isRooted(); if (isRooted) { // Option 1: Warn user showWarning('Device security compromised'); // Option 2: Restrict features disableSensitiveFeatures(); // Option 3: Block app (for high-security apps) blockApp(); } } ``` ## Security Checklist ### Before Release - [ ] Run `bunx capsec scan --severity high` - [ ] Remove all console.log statements - [ ] Disable WebView debugging - [ ] Remove development URLs - [ ] Verify no hardcoded secrets - [ ] Enable certificate pinning - [ ] Implement root/jailbreak detection - [ ] Add Content Security Policy - [ ] Use secure storage for credentials - [ ] Enable ProGuard (Android) - [ ] Verify ATS settings (iOS) ### Ongoing - [ ] Run security scans in CI/CD - [ ] Monitor for new vulnerabilities - [ ] Update dependencies regularly - [ ] Review third-party plugins - [ ] Audit authentication flows ## Resources - Capsec Documentation: https://capacitor-sec.dev - OWASP Mobile Top 10: https://owasp.org/www-project-mobile-top-10 - OWASP MASTG: https://mas.owasp.org/MASTG - Capgo Security Plugins: https://capgo.app