plugins/capacitor-quality/skills/capacitor-security/SKILL.md
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.
npx skillsauth add cap-go/capacitor-skills capacitor-securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Zero-config security scanning for Capacitor and Ionic apps.
# Scan current directory (no installation needed)
npx capsec scan
# Scan specific path
npx capsec scan ./my-app
# CI mode (exit code 1 on high/critical issues)
npx capsec scan --ci
# CLI output (default)
npx capsec scan
# JSON report
npx capsec scan --output json --output-file report.json
# HTML report
npx capsec scan --output html --output-file security-report.html
# Only critical and high severity
npx capsec scan --severity high
# Specific categories
npx capsec scan --categories secrets,network,storage
# Exclude test files
npx capsec scan --exclude "**/test/**,**/*.spec.ts"
| Rule | Severity | Description | |------|----------|-------------| | SEC001 | Critical | Hardcoded API Keys & Secrets | | SEC002 | High | Exposed .env File |
What Capsec Detects:
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' });
| 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',
});
| 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'],
},
};
| 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',
},
};
| 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>
| 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>
| 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',
});
| 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';
">
| 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']
);
| 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);
}
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Run Capsec Security Scan
run: npx 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
security-scan:
image: node:20
script:
- npx capsec scan --ci
artifacts:
reports:
security: security-report.json
only:
- merge_requests
- main
{
"exclude": [
"**/node_modules/**",
"**/dist/**",
"**/*.test.ts",
"**/*.spec.ts"
],
"severity": "low",
"categories": [],
"rules": {
"LOG002": {
"enabled": false
},
"SEC001": {
"severity": "critical"
}
}
}
npx capsec init
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();
}
}
npx capsec scan --severity highdevelopment
Complete guide to handling safe areas in Capacitor apps for iPhone notch, Dynamic Island, home indicator, and Android cutouts. Covers CSS, JavaScript, and native solutions. Use this skill when users have layout issues on modern devices.
development
Guide to using Konsta UI for pixel-perfect iOS and Material Design components in Capacitor apps. Works with React, Vue, and Svelte. Use this skill when users want native-looking UI without Ionic, or prefer a lighter framework.
development
Guide to using Ionic Framework components for beautiful native-looking Capacitor apps. Covers component usage, theming, platform-specific styling, and best practices for mobile UI. Use this skill when users need help with Ionic components or mobile UI design.
tools
Guide to accessing device logs on iOS and Android for Capacitor apps. Covers command-line tools, GUI applications, filtering, and real-time streaming. Use this skill when users need to view device logs for debugging.