capacitor-security
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCapacitor Security with Capsec
借助Capsec实现Capacitor应用安全
Zero-config security scanning for Capacitor and Ionic apps.
为Capacitor和Ionic应用提供零配置安全扫描。
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
- 用户希望保护其应用安全
- 用户咨询安全漏洞相关问题
- 用户需要运行安全审计
- 用户存在硬编码密钥问题
- 用户需要CI/CD安全扫描
- 用户咨询OWASP移动安全相关内容
Quick Start with Capsec
Capsec快速入门
Run Security Scan
运行安全扫描
bash
undefinedbash
undefinedScan current directory (no installation needed)
扫描当前目录(无需安装)
bunx capsec scan
bunx capsec scan
Scan specific path
扫描指定路径
bunx capsec scan ./my-app
bunx capsec scan ./my-app
CI mode (exit code 1 on high/critical issues)
CI模式(出现高/严重问题时返回退出码1)
bunx capsec scan --ci
undefinedbunx capsec scan --ci
undefinedOutput Formats
输出格式
bash
undefinedbash
undefinedCLI output (default)
CLI输出(默认)
bunx capsec scan
bunx capsec scan
JSON report
JSON报告
bunx capsec scan --output json --output-file report.json
bunx capsec scan --output json --output-file report.json
HTML report
HTML报告
bunx capsec scan --output html --output-file security-report.html
undefinedbunx capsec scan --output html --output-file security-report.html
undefinedFiltering
过滤选项
bash
undefinedbash
undefinedOnly critical and high severity
仅显示严重和高风险问题
bunx capsec scan --severity high
bunx capsec scan --severity high
Specific categories
指定分类
bunx capsec scan --categories secrets,network,storage
bunx capsec scan --categories secrets,network,storage
Exclude test files
排除测试文件
bunx capsec scan --exclude "/test/,**/*.spec.ts"
undefinedbunx capsec scan --exclude "/test/,**/*.spec.ts"
undefinedSecurity Rules Reference
安全规则参考
Secrets Detection (SEC)
密钥检测(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' });| 规则ID | 风险等级 | 描述 |
|---|---|---|
| SEC001 | 严重 | 硬编码API密钥和机密信息 |
| SEC002 | 高 | 暴露的.env文件 |
Capsec可检测的内容:
- AWS访问密钥
- Google API密钥
- Firebase密钥
- Stripe密钥
- GitHub令牌
- JWT密钥
- 数据库凭证
- 30+种密钥模式
修复示例:
typescript
// 错误示例 - 硬编码API密钥
const API_KEY = 'sk_live_abc123xyz';
// 正确示例 - 使用环境变量
import { Env } from '@capgo/capacitor-env';
const API_KEY = await Env.get({ key: 'API_KEY' });Storage Security (STO)
存储安全(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',
});| 规则ID | 风险等级 | 描述 |
|---|---|---|
| STO001 | 高 | 偏好设置中存储未加密的敏感数据 |
| STO002 | 高 | 使用localStorage存储敏感数据 |
| STO003 | 中 | SQLite数据库未加密 |
| STO004 | 中 | 文件系统存储敏感数据 |
| STO005 | 低 | 不安全的数据缓存 |
| STO006 | 高 | 未使用Keychain/Keystore存储凭证 |
修复示例:
typescript
// 错误示例 - 使用普通偏好设置存储令牌
import { Preferences } from '@capacitor/preferences';
await Preferences.set({ key: 'auth_token', value: token });
// 正确示例 - 使用安全存储
import { NativeBiometric } from '@capgo/capacitor-native-biometric';
await NativeBiometric.setCredentials({
username: email,
password: token,
server: 'api.myapp.com',
});Network Security (NET)
网络安全(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'],
},
};| 规则ID | 风险等级 | 描述 |
|---|---|---|
| NET001 | 严重 | HTTP明文传输 |
| NET002 | 高 | 缺少SSL/TLS证书绑定 |
| NET003 | 高 | Capacitor Server启用明文传输 |
| NET004 | 中 | 不安全的WebSocket连接 |
| NET005 | 中 | CORS通配符配置 |
| NET006 | 中 | 不安全的深度链接验证 |
| NET007 | 低 | Capacitor HTTP插件误用 |
| NET008 | 高 | URL参数中包含敏感数据 |
修复示例:
typescript
// 错误示例 - 生产环境使用HTTP
const config: CapacitorConfig = {
server: {
cleartext: true, // 生产环境绝对禁止!
},
};
// 正确示例 - 仅使用HTTPS
const config: CapacitorConfig = {
server: {
cleartext: false,
// 仅允许特定域名
allowNavigation: ['https://api.myapp.com'],
},
};Capacitor-Specific (CAP)
Capacitor特定规则(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',
},
};| 规则ID | 风险等级 | 描述 |
|---|---|---|
| CAP001 | 高 | WebView调试模式已启用 |
| CAP002 | 中 | 不安全的插件配置 |
| CAP003 | 低 | 生产环境启用详细日志 |
| CAP004 | 高 | 不安全的allowNavigation配置 |
| CAP005 | 严重 | 暴露原生桥接接口 |
| CAP006 | 严重 | 结合用户输入使用Eval |
| CAP007 | 中 | 缺少Root/越狱检测 |
| CAP008 | 低 | 不安全的插件导入 |
| CAP009 | 中 | 实时更新安全问题 |
| CAP010 | 高 | 不安全的postMessage处理器 |
修复示例:
typescript
// 错误示例 - 生产环境启用调试模式
const config: CapacitorConfig = {
ios: {
webContentsDebuggingEnabled: true, // 生产环境移除!
},
android: {
webContentsDebuggingEnabled: true, // 生产环境移除!
},
};
// 正确示例 - 仅在开发环境启用
const config: CapacitorConfig = {
ios: {
webContentsDebuggingEnabled: process.env.NODE_ENV === 'development',
},
};Android Security (AND)
Android安全规则(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
<!-- BAD -->
<application android:usesCleartextTraffic="true">
<!-- GOOD -->
<application
android:usesCleartextTraffic="false"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config">network_security_config.xml:
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>| 规则ID | 风险等级 | 描述 |
|---|---|---|
| AND001 | 高 | Android允许明文传输 |
| AND002 | 中 | Android调试模式已启用 |
| AND003 | 中 | 不安全的Android权限 |
| AND004 | 低 | Android允许备份 |
| AND005 | 高 | 导出组件未设置权限 |
| AND006 | 中 | WebView启用JavaScript但未设置防护措施 |
| AND007 | 严重 | 不安全的WebView addJavascriptInterface |
| AND008 | 严重 | 硬编码签名密钥 |
修复AndroidManifest.xml:
xml
<!-- 错误示例 -->
<application android:usesCleartextTraffic="true">
<!-- 正确示例 -->
<application
android:usesCleartextTraffic="false"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config">network_security_config.xml:
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)
iOS安全规则(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
<!-- 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>| 规则ID | 风险等级 | 描述 |
|---|---|---|
| IOS001 | 高 | 应用传输安全已禁用 |
| IOS002 | 中 | 不安全的Keychain访问 |
| IOS003 | 中 | URL Scheme未验证 |
| IOS004 | 低 | iOS剪贴板包含敏感数据 |
| IOS005 | 中 | 不安全的iOS权限 |
| IOS006 | 低 | 后台应用刷新导致数据暴露 |
| IOS007 | 中 | 缺少iOS越狱检测 |
| IOS008 | 低 | 敏感界面未禁用截图 |
修复Info.plist:
xml
<!-- 错误示例 - 禁用ATS -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- 正确示例 - 仅设置特定例外 -->
<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)
认证安全规则(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',
});| 规则ID | 风险等级 | 描述 |
|---|---|---|
| AUTH001 | 严重 | 弱JWT验证 |
| AUTH002 | 高 | 不安全的生物识别实现 |
| AUTH003 | 高 | 弱随机数生成 |
| AUTH004 | 中 | 缺少会话超时 |
| AUTH005 | 高 | 缺少OAuth State参数 |
| AUTH006 | 严重 | 认证中存在硬编码凭证 |
修复示例:
typescript
// 错误示例 - 未验证JWT
const decoded = jwt.decode(token);
// 正确示例 - 验证JWT签名
const decoded = jwt.verify(token, publicKey, {
algorithms: ['RS256'],
issuer: 'https://auth.myapp.com',
audience: 'myapp',
});WebView Security (WEB)
WebView安全规则(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
<!-- 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';
">| 规则ID | 风险等级 | 描述 |
|---|---|---|
| WEB001 | 严重 | WebView JavaScript注入 |
| WEB002 | 中 | 不安全的iframe配置 |
| WEB003 | 中 | 加载外部脚本 |
| WEB004 | 中 | 缺少内容安全策略(CSP) |
| WEB005 | 低 | 使用target _blank但未设置noopener |
修复 - 添加CSP:
html
<!-- 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)
加密安全规则(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']
);| 规则ID | 风险等级 | 描述 |
|---|---|---|
| CRY001 | 严重 | 弱加密算法 |
| CRY002 | 严重 | 硬编码加密密钥 |
| CRY003 | 高 | 不安全的随机IV生成 |
| CRY004 | 高 | 弱密码哈希 |
修复示例:
typescript
// 错误示例 - 使用弱算法
const encrypted = CryptoJS.DES.encrypt(data, key);
// 正确示例 - 使用强算法
const encrypted = CryptoJS.AES.encrypt(data, key, {
mode: CryptoJS.mode.GCM,
padding: CryptoJS.pad.Pkcs7,
});
// 错误示例 - 硬编码密钥
const key = 'my-secret-key-123';
// 正确示例 - 派生密钥
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)
日志安全规则(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);
}| 规则ID | 风险等级 | 描述 |
|---|---|---|
| LOG001 | 高 | 控制台日志包含敏感数据 |
| LOG002 | 低 | 生产环境存在控制台日志 |
修复示例:
typescript
// 错误示例 - 记录敏感数据
console.log('User password:', password);
console.log('Token:', authToken);
// 正确示例 - 脱敏敏感数据
console.log('User authenticated:', userId);
// 使用条件日志
if (process.env.NODE_ENV === 'development') {
console.debug('Debug info:', data);
}CI/CD Integration
CI/CD集成
GitHub Actions
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.jsonyaml
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.jsonGitLab CI
GitLab CI
yaml
security-scan:
image: oven/bun:latest
script:
- bunx capsec scan --ci
artifacts:
reports:
security: security-report.json
only:
- merge_requests
- mainyaml
security-scan:
image: oven/bun:latest
script:
- bunx capsec scan --ci
artifacts:
reports:
security: security-report.json
only:
- merge_requests
- mainConfiguration
配置
capsec.config.json
capsec.config.json
json
{
"exclude": [
"**/node_modules/**",
"**/dist/**",
"**/*.test.ts",
"**/*.spec.ts"
],
"severity": "low",
"categories": [],
"rules": {
"LOG002": {
"enabled": false
},
"SEC001": {
"severity": "critical"
}
}
}json
{
"exclude": [
"**/node_modules/**",
"**/dist/**",
"**/*.test.ts",
"**/*.spec.ts"
],
"severity": "low",
"categories": [],
"rules": {
"LOG002": {
"enabled": false
},
"SEC001": {
"severity": "critical"
}
}
}Initialize Config
初始化配置
bash
bunx capsec initbash
bunx capsec initRoot/Jailbreak Detection
Root/越狱检测
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();
}
}typescript
import { IsRoot } from '@capgo/capacitor-is-root';
async function checkDeviceSecurity() {
const { isRooted } = await IsRoot.isRooted();
if (isRooted) {
// 选项1:警告用户
showWarning('设备安全已受损');
// 选项2:限制功能
disableSensitiveFeatures();
// 选项3:阻止应用运行(适用于高安全要求应用)
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)
- 运行
bunx capsec scan --severity high - 移除所有console.log语句
- 禁用WebView调试
- 移除开发环境URL
- 确认无硬编码密钥
- 启用证书绑定
- 实现Root/越狱检测
- 添加内容安全策略(CSP)
- 使用安全存储保存凭证
- 启用ProGuard(Android)
- 验证ATS设置(iOS)
Ongoing
日常维护
- Run security scans in CI/CD
- Monitor for new vulnerabilities
- Update dependencies regularly
- Review third-party plugins
- Audit authentication flows
- 在CI/CD中运行安全扫描
- 监控新漏洞
- 定期更新依赖
- 审核第三方插件
- 审计认证流程
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
- Capsec文档: https://capacitor-sec.dev
- OWASP移动应用安全Top10: https://owasp.org/www-project-mobile-top-10
- OWASP移动应用安全测试指南: https://mas.owasp.org/MASTG
- Capgo安全插件: https://capgo.app