关于 capacitor-security
用于审计和加固 Capacitor 应用安全层的技能,面向排查移动安全风险或渗透测试问题的开发者,涵盖扫描器结果及应用包、存储、网络、WebView、桥接和原生配置检查。
主要功能
- 01运行 Capgo 扫描器并分类结果
- 02检查应用包中的秘密信息和存储
- 03网络传输与证书指引
- 04审查 WebView 和原生桥接
- 05加固 Android 与 iOS 清单配置
适用场景
- 01依据移动安全问题审计应用
- 02检查构建产物中的凭据泄露
- 03保护令牌存储和网络传输
- 04审计桥接访问与平台设置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill capacitor-security安装后在 Claude Code 中输入/capacitor-security确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.jsonreferences/capsec-scanner.mdnetwork.mdplatform-hardening.mdsecrets-and-storage.mdwebview-and-bridge.md详细介绍
Capacitor 安全
审计并强化 Capacitor 应用的应用层:包中的机密信息、设备端存储、网络传输、WebView 和原生桥接暴露面,以及平台清单。
适用场景
在以下情况下触发:
- 用户要求进行安全审计、OWASP Mobile Top 10 / MASVS 审查,或希望修复渗透测试发现的问题。
- 用户希望运行或解读
@capgo/capgo-sec(capsec)结果,或处理SEC001、STO002、NET003、CAP004、AND004、IOS001等规则 ID。 src/、dist/、www/或capacitor.config.*中出现 API 密钥、服务角色密钥或.env值。- 身份验证令牌存储在
Preferences.set、localStorage、IndexedDB 或纯文本 SQLite 中。 capacitor.config.*包含server.cleartext: true、server.url、过于宽泛的server.allowNavigation、android.allowMixedContent或webContentsDebuggingEnabled: true。- 原生文件包含
NSAllowsArbitraryLoads、android:usesCleartextTraffic="true"、android:allowBackup="true"、android:debuggable,或未设置权限的导出组件。 - 用户需要证书固定、内容安全策略、截图保护或 root / 越狱检测。
请勿用于:
- Xcode 构建设置、增强型安全、指针身份验证、栈 / 堆强化 →
capacitor-ios-security-hardening。 - Universal Links / App Links 设置 →
capacitor-deep-linking(此技能仅涵盖传入 URL 的验证)。 - 隐私清单、App Review 拒绝问题 →
capacitor-apple-review-preflight;应用商店列表 →capacitor-app-store。 - CI 中的流水线结构和签名机密信息 →
capacitor-ci-cd。 - 实时更新安装和渠道 →
capgo-live-updates(此技能仅涵盖包加密)。 - 运行时崩溃和 WebView 检查 →
debugging-capacitor。
工作流
- 先检查,再编辑。 阅读
capacitor.config.ts|json、package.json(Capacitor 主版本、已安装插件)、android/app/src/main/AndroidManifest.xml、android/app/src/main/res/xml/network_security_config.xml(如果存在)、ios/App/App/Info.plist、*.entitlements和index.html。 - 扫描。 从项目根目录运行 Capgo 扫描器(Node 18+):
npm 包名为npx @capgo/capgo-sec@latest scan --severity medium@capgo/capgo-sec;它会安装capsec二进制文件。由于 npm 上不存在名为capsec的包,npx capsec无法运行。 - 用 grep 查找扫描器会漏掉的问题(参见验证)。先构建 Web 应用,再对
dist/或www/执行 grep:打包工具会内联import.meta.env.*和process.env.*的值。 - 在进行重大更改前,先分类并报告。 按严重、 高、中、低分组列出发现项及其文件和行号。对于会改变行为的更改,先询问用户:证书固定(证书轮换时可能导致用户无法访问)、阻止已 root 的设备、移除
allowNavigation主机,以及严格的 CSP。 - 按领域修复,加载下方对应的参考资料。
- 重新运行扫描和验证检查,然后运行
npx cap sync,并在设备上测试发布构建。
Capacitor 特有的陷阱
- Bundle 中没有任何内容是机密。 Web 资源会随 IPA/APK 一起打包,
capacitor.config.json也会被复制到原生资源中。plugins.*配置中的值(包括@capgo/capacitor-env)都可以被提取。请将涉及机密信息的调用移至后端。 allowNavigation会授予桥接访问权限。 在 Android 上,每个allowNavigation条目都会加入桥接的允许来源规则,因此来自这些主机的页面可以调用你的原生插件。只列出你控制的主机。请改用@capacitor/browser或@capgo/inappbrowser打开第三方页面。server.url和server.cleartext仅供开发使用。 Capacitor 文档指出,这两项“并非用于生产环境”。如果提交了局域网 IP,打包后的 WebView 就会通过 HTTP 加载远程代码。- 发布版本中的 WebView 可调试。
ios.webContentsDebuggingEnabled/android.webContentsDebuggingEnabled默认仅在调试构建中启用。硬编码为true会让任何发布构建中的 WebView 都能通过 Safari /chrome://inspect访问。 - CapacitorHttp 不等于证书固定。
plugins.CapacitorHttp.enabled只会将fetch/XHR 请求路由到原生网络层。证书固定需要使用@capgo/capacitor-ssl-pinning,它会挂接到 CapacitorHttp。 - 生物识别提示不等于身份验证。 在已 root/越狱的设备上,
verifyIdentity()可以被 Hook。请将机密信息置于accessControl保护之下(与硬件绑定的 Keychain/Keystore 项目),并在服务端验证会话。 - 通过自定义 Scheme 实现的 OAuth 需要 PKCE。 任何应用都可以注册
myapp://。请使用 PKCE,并优先使用 Universal/App Links 进行重定向。 - Live Update Bundle 除非加密,否则都是公开的。 私有频道会限制哪些人可以接收 Bundle,但不会让内容保密。
参考资料
仅当涉及相关主题时才加载参考资料。
| 参考资料 | 加载时机 |
|---|---|
| references/capsec-scanner.md | 运行扫描器、查看规则 ID、设置 CI 门禁、生成 JSON/HTML 报告 |
| references/secrets-and-storage.md | 硬编码密钥、.env 泄漏、令牌存储、Keychain/Keystore、加密 SQLite、日志记录 |
| references/network.md | HTTPS/ATS/明文传输、network_security_config.xml、证书固定、CORS 与 CapacitorHttp 的区别 |
| references/webview-and-bridge.md | CSP、allowNavigation、iframe、postMessage、eval、深层链接/OAuth 验证 |
| references/platform-hardening.md | AndroidManifest 标志、R8、iOS Info.plist/entitlements、屏幕截图保护、root/越狱检测、Live Update 加密 |
此处未涵盖 Xcode 编译器/链接器加固:请使用 capacitor-ios-security-hardening。
验证
在项目根目录运行。对于发布构建,每个 grep 都应无返回结果,或仅返回有意保留且已有文档说明的匹配项。
# 1. Scanner gate (exit code 1 on high/critical)
npx @capgo/capgo-sec@latest scan --ci
# 2. Dev-only config left in capacitor.config
grep -nE "cleartext|server:\s*\{|\"url\"|url:|allowMixedContent|webContentsDebuggingEnabled" capacitor.config.*
# 3. Secrets in the built bundle (build first)
npm run build
grep -rnE "sk_live_|sk-ant-|sk-proj-|AKIA[0-9A-Z]{16}|service_role|-----BEGIN (RSA |EC )?PRIVATE KEY" dist/ www/ 2>/dev/null
# 4. Tokens in plain storage
grep -rnE "(Preferences\.set|localStorage\.setItem)\(.*(token|password|secret|jwt)" -i src/
# 5. Android manifest flags
grep -nE "usesCleartextTraffic|allowBackup|debuggable|exported=\"true\"" android/app/src/main/AndroidManifest.xml
# 6. iOS transport and file sharing
plutil -p ios/App/App/Info.plist | grep -E "NSAllowsArbitraryLoads|NSExceptionAllowsInsecureHTTPLoads|UIFileSharingEnabled|LSSupportsOpeningDocumentsInPlace"
# 7. Native projects pick up config changes
npx cap sync
然后在设备上安装发布构建并确认:登录正常、API 调用成功(证书固定未造成影响),且 Safari Web Inspector / chrome://inspect 无法连接。
错误处理
| 错误 | 原因 | 修复方法 |
|---|---|---|
net::ERR_CLEARTEXT_NOT_PERMITTED(Android) | HTTP 请求被拦截;自 API 28 起默认禁用明文传输 | 使用 HTTPS。仅在开发环境热重载时,在仅用于开发的配置中使用 server.cleartext: true。切勿发布 usesCleartextTraffic="true"。 |
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.(iOS,NSURLError -1022) | ATS 下使用了 HTTP URL | 使用 HTTPS。如果无法避免使用旧版主机,请添加范围严格的 NSExceptionDomains 条目,切勿使用 NSAllowsArbitraryLoads。 |
... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present | 后端不允许 WebView 来源 | 在服务器上允许 capacitor://localhost(iOS)和 https://localhost(Android 默认值),或启用 CapacitorHttp。不要对需要身份验证的端点添加 Access-Control-Allow-Origin: *。 |
Refused to connect to '<url>' because it violates the following Content Security Policy directive | CSP connect-src 中缺少主机 | 将确切的 API 来源添加到 connect-src。不要退而使用 *。 |
| 证书续期后固定证书的请求失败 | 仅固定了旧的叶证书 | 固定 CA 或中间证书,并添加备用证书;在轮换前先发布备用证书。 |
npm error 404 Not Found - GET https://registry.npmjs.org/capsec | 软件包名称错误 | 使用 npx @capgo/capgo-sec@latest scan。 |
No protected credentials found / No protected data found(代码 21,@capgo/capacitor-native-biometric) | 未使用 accessControl 存储任何内容、刚完成安装,或因生物识别信息变更而导致条目失效 | 按“已注销”处理:向服务器重新进行身份验证,然后使用 AccessControl.BIOMETRY_CURRENT_SET 或 BIOMETRY_ANY 再次存储。 |
资源
- Capacitor 安全指南:https://capacitorjs.com/docs/guides/security
- Capgo 安全扫描器:https://capgo.app/security-scanner/(源代码:https://github.com/Cap-go/capgo-sec)
- OWASP 移动端十大风险:https://owasp.org/www-project-mobile-top-10/
- OWASP MASVS / MASTG:https://mas.owasp.org/
评论
支持 Markdown