Claude-skill-registry capacitor-security
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.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/capacitor-security" ~/.claude/skills/majiayu000-claude-skill-registry-capacitor-security && rm -rf "$T"
manifest:
skills/data/capacitor-security/SKILL.mdsource content
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:
<!-- BAD --> <application android:usesCleartextTraffic="true"> <!-- GOOD --> <application android:usesCleartextTraffic="false" android:allowBackup="false" android:networkSecurityConfig="@xml/network_security_config">
network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">api.myapp.com</domain> <pin-set> <pin digest="SHA-256">your-pin-hash</pin> </pin-set> </domain-config> </network-security-config>
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:
<!-- BAD - Disables ATS --> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <!-- GOOD - Specific exceptions only --> <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>legacy-api.example.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict>
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:
<!-- index.html --> <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