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
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
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
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:
// 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:
// 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:
// 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:
// 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:
network_security_config.xml:
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:
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:
// 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:
<meta http-equiv="Content-Security-Policy" content=" default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.myapp.com; font-src 'self'; frame-ancestors 'none'; ">
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:
// 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:
// 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 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 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 { "exclude": [ "/node_modules/", "/dist/", "/*.test.ts", "/*.spec.ts" ], "severity": "low", "categories": [], "rules": { "LOG002": { "enabled": false }, "SEC001": { "severity": "critical" } } }
Initialize Config bunx capsec init
Root/Jailbreak Detection 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