您的应用程序通过 QA 检查,部署到生产环境,所有人都松了一口气。 然后,在野外出现依赖项问题,或者不小心更改配置文件暴露了您认为是内部的端点,或者实时更新推送了一个坏的 JavaScript 包到设备上,这些设备将永远不会看到您的预发布检查。 这就是组织通常学习到应用程序漏洞扫描不是扫描器问题。 而是生命周期问题。
购买工具并点击“扫描”并不是困难的部分。 构建一个能够在部署后捕捉缺陷、保持运行并将发现转化为修复的系统才是困难的。 在 CapacitorJS 和 Electron 堆栈中,这变得更加复杂,因为您的应用程序可以在发布后通过 Web 层更新、内容更改和远程配置而改变。
一个健壮的设置必须涵盖code,依赖项、容器、正在运行的服务以及在二进制文件已在用户设备上的情况下交付的捆绑包。它还必须符合工程师的工作方式。如果扫描速度慢、噪音大或脱离了拉取请求和发布工作流程,管道就会被绕过。如果您正在通过更广泛的 应用风险评估流程, 应用程序漏洞扫描成为一个更大的运营模型的一部分,而不是简单的遵守性检查。
内容目录
为什么主动性漏洞扫描很重要
星期五下午是弱扫描程序暴露的时间。新依赖CVE出现,安全人员会问哪些应用程序受影响,答案取决于谁仍然有上个月的报告。移动和桌面团队有一个额外的问题。即使后端已经修复,部署的客户端也可以继续运行脆弱的code,直到用户更新,或者直到团队有一个控制的方式来修补生产中的内容。
这就是为什么主动扫描很重要。它给团队提供了当前的清单,明确的每个发现的责任人,以及从发现到验证修复的更快的路径。它还关闭了许多指南忽略的漏洞。对于Capacitor和Electron应用程序,风险不仅仅是发布日。您需要在部署后继续扫描和评估,特别是如果应用程序可以通过Web资产、远程配置、插件或实时更新改变行为。进行正式 应用程序风险评估 通常发现,团队认为难的是运行扫描器。难的是证明生产中当前暴露的内容。
只有当修复措施内置时,扫描才有意义
一个只会将发现dump到PDF的扫描器会创建一个后续工作清单,而不是保护。一个工作的程序会将发现与服务负责人关联,打开包含足够上下文的票据,并记录修复后重新测试。 如果缺少了这个交接流程,团队要么会忽略报告,要么会花费几天时间争论是否存在问题。
使用简单的规则。
实践规则: 如果发现的问题无法分配、修复和验证,那么它是安全数据收集,而不是风险降低。
工作流程必须覆盖整个生命周期。确定资产范围。扫描code、依赖项、构建产物和正在运行的服务。根据攻击性和暴露程度进行分类。使用正常的交付路径进行修复,时间允许时。使用发布后路径进行修复,尤其是对于可以在商店发布外更新Webcode的应用程序。然后重新扫描以确认暴露已消失。
等待会很快变得昂贵。
被动清理会在可预测的方式中浪费工程时间。开发人员会回归陈旧的code。安全团队会在多个工具中重新检查相同的问题。发布经理会开始批准例外,因为发布窗口已经延迟。结果是噪音、延迟和很少的信心。
主动扫描改变了经济。发现的问题会在引入它们的提交附近出现。责任清晰。生产暴露更容易回答。并且,当一个在线应用程序需要快速的后部署修复时,团队已经知道受影响的层次和是否需要提交商店、服务器端更改或受控的在线更新。
应用程序漏洞扫描的四大支柱
有效的应用程序漏洞扫描通常涉及四个类别的协同工作。不是因为供应商喜欢缩写,而是因为每种方法都看到不同的风险片段。如果您依赖一种扫描器类型,您将获得一种真相和几个盲点。

每种扫描器都擅长什么
SAST reads source code, bytecode, or compiled artifacts without running the app. It’s best when developers are still changing code and need quick feedback close to the commit. SonarQube and Semgrep are common choices here because they fit well into pull requests and CI.
DAST 从外部击中正在运行的应用程序。它对于身份验证错误、错误的 HTTP 头、服务器行为、暴露的路由和只在请求通过整个堆栈时才显示的问题非常有用。OWASP ZAP 和 Burp Suite 是熟悉的选项。
IAST 通过instrumentation或代理坐在更接近运行时,结合内部可见性与实时执行。它更具操作性,但可以填补“这个模式看起来风险很大”和“这个请求路径是可利用的”之间的差距。
SCA 跟踪第三方包和您的依赖树中的已知问题。对于大多数现代团队来说,这比源代码扫描更容易立即行动,因为应用程序的大部分code都依赖于外部包。Snyk、Dependabot 和类似工具是常见的入口点。
If you’re also dealing with APIs that have to satisfy store and platform requirements, the security checks in your app pipeline should line up with the API code
Comparison of Vulnerability Scanning Types
| 类型 | 什么时候运行 | 发现什么 | 关键优势 |
|---|---|---|---|
| SAST | 编码、pull请求和构建期间 | 有风险的code模式和不安全的数据流 | 快速反馈之前部署 |
| DAST | 针对正在测试或运行的应用 | 运行时错误、暴露的行为、配置错误 | 像攻击者一样看到应用 |
| IAST | 在执行过程中进行装饰 | Code级别和运行时问题 | 通过执行感知提高精度 |
| SCA | 在依赖安装、构建和更新事件中 | 易受攻击的第三方包和传递依赖 | 快速暴露供应链风险 |
How to layer them without wasting time
很多团队在早期过度构建。他们将每个扫描器连接到每个阶段,产生重复的警报,然后 wondered 为什么开发人员会静音通知。更清洁的方法是分阶段覆盖。
- 使用 SAST 快速获得 code feedback: 在 pull requests 运行它,并将规则保持在语言和框架使用的模式上。
- 使用 SCA 在每个依赖项变化时: 不要等待预定的扫描才能了解包更新引入的风险。
- 使用 DAST 在真实环境中: 将其运行在 staging 或 review 应用程序中,具有身份验证,以便它看到真实的流程。
- 使用 IAST 选择性地: 保留它用于高风险服务,额外的上下文值得付出运营开销。
正确的问题不是“我们应该购买哪个扫描器?”而是“我们现在对什么类别的弱点视而不见?”
这种框架使程序保持实用。每个柱子都有其位置,因为它捕获了其他不会捕获的东西。
扫描现代应用架构
一家团队发布了一个干净的移动版本,通过了常规扫描,发布上线。三天后,它推送了一个JavaScript包更新来修复一个UIbug。这个包改变了客户端验证,暴露了shell不应该调用的桥接方法,并且没有经过同样的安全检查。原始发布的版本被扫描过了。现在的code用户正在运行的版本没有。

传统程序的缺陷
A lot of scanning programs still center on two targets: source code in the repo and endpoints exposed by a running service. That covers a normal web app reasonably well. It does not cover architectures where meaningful changes happen after deployment, across multiple artifacts, or inside a client shell that can load updated content.
CapacitorJS和Electron暴露了这个缺陷。可安装的二进制文件只是攻击面的一部分。JavaScript包,CSS,配置文件,特性标志,远程内容,预加载脚本,原生桥接,更新通道等,都会影响到人们正在使用的应用的安全态势。
Wiz在其 应用程序漏洞扫描分析中指出:许多团队在发布前强调安全检查,而在发布后改变却被低估。对于实时更新的应用来说,这是一个过程缺陷,而不是边缘案例。
把“应用”视为一个单元是实践上的错误。现代交付堆栈是层次化的,每层都有不同的故障模式:
- 客户端包风险: 更新的 Web 资产可能引入不安全的 DOM 处理、弱化认证流程或改变API目标而无需新二进制审查
- 容器风险: 服务镜像可能携带陈旧的 OS 包、暴露的工具或坏的基准镜像,即使应用code看起来干净
- 运行时漂移: 生产环境可能与 staging 分离,通过环境变量、侧车、秘钥注入、准入规则和特性标志
- Shell 风险: Electron 和Capacitor wrapper 添加了权限模型、IPC 或桥接表面、本地存储问题和标准 Web 扫描无法看到的更新机制
现代交付路径中需要添加什么
容器化服务需要比仓库扫描更进一步。扫描镜像期间构建,扫描最终的工件之前部署,比较集群中运行的内容与批准的内容。Trivy 是一个常见的起点,因为它在同一工作流中涵盖了文件系统包和容器镜像。然而,这仍然不足以解决问题。没有运行时上下文的镜像发现会导致长长的修复队列,包含code路径无法访问的问题
实时更新应用需要更严格的模型。把每个包视为一个独立的发布工件,拥有自己的安全门槛、版本记录和回滚路径
通常意味着四个控制项:
- 在发布包之前扫描网络层
- 记录每个设备安装的包版本
- 签署更新并验证传递完整性
- 以小规模分组发布,以便坏的更新被包含
这也改变了所有权。安全审查不能再仅限于商店提交或桌面打包。必须有人拥有更新频道、签名过程、包清单和回滚杀switch。否则,扫描程序就有一个盲点。
架构也改变了扫描器的范围。一个单独的服务和一个分布式舰队不会产生相同的审查负担、凭证模型或警报路由。处理 单体架构和微服务架构的团队 通常发现漏洞所有权比扫描覆盖度更难
预发布扫描回答一个狭窄的问题:在发布时间,这个工件是否接受?它对包、镜像、配置或shell变更后推送的任何内容都没有说什么,除非这些工件经过自己的检查。
That is the part many guides skip. Modern app vulnerability scanning has to follow the code that is running in production, including code delivered after the original deploy.
正在生产中的__CAPGO_KEEP_0__,包括__CAPGO_KEEP_1__在原有部署后传递的内容。
A团队在周五发布了一个干净的移动版本,然后在周二推送了一个修复收银机器故障的实时Web包。应用商店的构建通过了每个安全检查。周二的包并没有经过同样的路径,现在生产环境正在运行code,您的管道从未审查过。这个缺口正是扫描程序失败的地方。

The pipeline has to match how the app is delivered. For a web app, that usually means code, dependencies, containers, and a deployed environment. For Capacitor and Electron apps, it also means the post-deployment update path. If your scanners stop at merge or store submission, they miss one of the highest-risk points in the release lifecycle.
实践中有效的模式是分阶段扫描。早期进行廉价的检查,后期进行更深入的检查,并在定期的时间间隔内进行post-deployment扫描。那些想要获得更快安全反馈的团队通常会采用上述描述的习惯。 如何CI/CD工作流程改善应用程序安全开始使用管道形状
一个可行的基准线看起来像这样:
拉取请求阶段:
- SAST、SCA、机密扫描和基础设施作为代码和构建配置的政策检查。 SAST, SCA, secrets scanning, and policy checks on infrastructure-as-code and build configs.
- 全依赖项解析、容器扫描、SBOM生成和签名艺术ifact创建。 如何CI/CD工作流程改善应用程序安全
- 预发布阶段: 对一个真实环境进行认证DAST扫描,检查暴露的管理员路由、弱头和风险默认配置。
- 发布后阶段: 预定外部验证、运行时可见性和扫描任何到达用户的实时更新包。
最后阶段经常被跳过。对于实时更新应用程序,推送的包应被视为发布,而不是静态资产上传。
实践中的GitHub Actions示例
基本工作流可能结合SonarScanner进行静态分析、Snyk进行依赖项和Trivy进行容器镜像。
name: security-pipeline
on:
pull_request:
push:
branches: [main]
jobs:
sast-and-sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test, --ci
- name: Sonar scan
run: npx sonarqube-scanner
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Snyk dependency scan
run: npx snyk test
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
container-scan:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t app:${{ github.sha }} .
- name: Trivy image scan
run: trivy image --exit-code 1 app:${{ github.sha }}
这足以开始,但不足以管理发布。生产管道通常需要四个附加功能:将结果上传到SARIF,以便发现的结果可以在开发人员已经工作的位置。将SBOM与构建工件一起保存。为拉取请求和发布候选人定义单独的失败规则。创建一个发布清单,将提交、工件哈希、依赖项快照和实时更新应用程序的包版本联系起来。
几个实现细节决定了管道是否被使用或跳过:
- 根据政策而不是发现量进行门控: 阻止构建定义的条件,如严重级别、已知利用或可达的脆弱code。
- 保持扫描速度以保留信任: 缓存依赖项,重用扫描数据库,并将长时间运行的作业从 pull 请求路径中分离。
- 使用身份验证运行 DAST: 匿名爬行很少能够到达处理钱、权限或账户变更的code。
- 将建议检查与发布阻塞器分开: 开发者会忽略整个系统,如果每个警告都会阻止交付。
- 在发布之前扫描更新包: 对于Capacitor或Electron的实时更新,检查更改的Web资产,附加扫描结果到包记录,并保留回滚元数据与发布一起。
以下是一个好的教程,配合您自己的实现工作:
什么需要门槛,什么需要报告
硬门槛应该狭窄且可辩护。广泛的阻塞规则看起来在纸上很严格,但通常会训练团队绕过安全而不是使用它。
成熟管道中的一个有效政策是简单的:
构建门槛规则: 阻止新引入的关键问题,阻止可利用的依赖性发现在可到达的路径中,并将较低风险的发现发送到拥有者和截止日期的正常修复队列中。
发布后需要自己的门控机制。 在发布一个live包之前,扫描更改的文件,验证签名,记录谁批准了发布,并将包ID附加到部署记录中。 当两个星期后出现问题时,那种可追溯性让你快速回答困难的问题:哪些用户接收了它,哪个code包含在它中,是否回滚足够还是需要强制更新。
解释结果和优先修复
一份扫描报告变得昂贵的那一刻,团队停止信任它。 通常发生在几轮噪音发现、重复票据和不通过手动审查的阻塞器之后。 好的分级修复问题之前就变得是一个文化问题。
切除假阳性之前让它们耗尽注意力
噪音有熟悉的原因。 规则保持启用状态,用于应用程序不使用的框架。 DAST在没有登录上下文的情况下运行,因此它会错过重要的流程并仍然产生弱猜测。 SAST、SCA、容器和运行时工具都以不同的方式描述相同的底层问题,然后将其分发到不同的队列。
首要任务是使发现可信。
团队通过调整检查项来适应他们运行的栈,使用身份验证扫描,特别是当深度很重要时,且在结果到达开发人员之前进行去重复处理。基于证据的验证和相关性有所帮助,但它们并不能代替政策调整。如果扫描器无法区分支付路径中的可达问题和废弃模块中的死code,则输出需要在到达回滚列表之前再进行一层审查。
有效的分级流程应该如下:
- 移除无法应用的发现: 如果应用程序不使用规则目标的运行时、包、端点类或功能,禁用或限制该规则。
- 将重复项合并为一个修复项: 一个弱点应该有一个负责人、一个截止日期和一个讨论线索。
- 使用身份验证重新扫描风险集中在哪里: 管理员面板、基于角色限制的流程、内部API和账户恢复路径通常看起来很干净,直到扫描器可以登录。
- 尽早附加业务背景: 反射型XSS在公共计费屏幕上是一个不同的问题,而在内部支持工具上出现相同的漏洞。
根据攻击性和爆炸半径进行优先排序:
扫描器严重性是一个起点。它不是工作队列。
我首先检查四个方面。问题是否在运行中的应用中可达。受影响的路径是否暴露给用户或互联网。是否有主动利用或成熟的利用路径的证据。团队是否可以快速降低风险使用补丁、配置更改、功能标志或临时控制。
That approach changes decisions fast. A medium-severity bug in an exposed authentication flow can outrank a higher-severity finding buried behind admin access and a WAF rule. A dependency CVE with no reachable code path usually drops below a smaller issue that sits directly on a payment or session boundary.
使用简单的过滤器进行日常筛查:
| 问题 | 是 | 否 |
|---|---|---|
| 生产环境中是否可达受影响的路径? | 提高紧急程度 | 直到可达性发生变化时才延后 |
| 是否暴露给未信任的用户或互联网? | 作为前线紧急修复 | 排在暴露问题之后 |
| 是否有活跃的利用、公开的利用或攻击者强烈的兴趣? | 立即修复 | 继续风险评估 |
| 是否可以通过补丁、配置更改或杀死switch减少风险? | 优先修复风险 | 计划code的修复和测试覆盖 |
根据真实攻击者的机会而不是报告量进行排序。
修复工作应该与发布路径相关联
优先级应该以一个可以由交付系统强制执行的动作结束。否则,团队会在Slack上同意风险,但仍会在下周发布包含漏洞的code。
对于标准的Web和移动后端,意味着将高置信度的发现转换为跟踪修复,拥有所有者、截止日期和验证标准。对于Capacitor和Electron应用程序,需要添加一个额外的步骤。询问问题是否位于实时更新层中,并且是否可以在不等待商店审查的情况下进行修复。这种在部署后做出的决定是许多程序的弱点。它们可以检测问题,但无法快速关闭已经在用户设备上的code问题。
如果您的团队支持热修复发布,请定义现在的交接:哪些发现适合进行出局的捆绑更新,谁批准它,如何分阶段发布,以及什么回滚信号可以停止发布。这 使用Capgo部署热修复的五步流程 对于使该路径正常运作而不是在事故中临时应对,__CAPGO_KEEP_0__是一个有用的参考。
实时更新中的快速修复
发现漏洞只是工作的一半。下一个问题是是否可以快速推送安全修复到受影响的用户中,以至于它对他们来说是有意义的。
对于服务器端应用程序,修补通常意味着重新部署服务。对于CapacitorJS和Electron应用程序,许多紧急修复都存在于web层:JavaScript逻辑、渲染路径、内容规则、特性标志、副本或配置。等待应用商店审查来纠正这些情况通常对于实际的事件响应工作流太慢了。
当商店审查太慢时
部署后差距是实时更新从便利工具转变为安全模型的一部分的地方。如果用户已经持有易受攻击的包、不安全的配置或破坏的-sanitization规则,您需要一种控制的方式来快速替换它。

对于这种类型的问题,团队通常需要在一个工作流中具备四种能力:
- 目标发布渠道: 首先对内部用户进行推送,然后是小规模的生产测试,然后是更广泛的发布。
- 包签名和版本历史: 知道确切发生了什么,并防止未经控制的艺术品发货。
- Per-device observability: 通过设备和捆绑包版本验证采用情况并调查失败原因。
- Automatic rollback: 如果修复创建了新的故障模式,快速回滚。
One option in this space is Capgo的热修复部署工作流程,该工作流程可以在不等待商店审批的情况下将签名的Web捆绑包更改应用到Capacitor和Electron应用中。这种机制在安全管道中最适合当它被视为一个正常的发布路径,具有批准、审计和回滚功能,而不是一个侧门。
How to patch safely
快速修复会带来风险,如果更新路径不当。不要通过创造另一个部署通道来应对一个安全问题。
A safe operating pattern looks like this:
- 复制并限定问题 在受影响的捆绑包或配置中。
- 修复必要的文件 以此来保持发布的范围小。
- 扫描修改的包 发布前
- 首先在一个狭窄的渠道中发布 并监测采用率和错误日志。
- 逐渐推广 一旦修复稳定
- 直到发布完成 在紧急情况下,更新过程应该像受时间压力影响的有条理的发布工程一样感觉,而不是手动解决方案。
尤其是在受监管的环境中,这一点尤为重要。如果您的移动或桌面 shell 可以接收动态内容,那么该交付路径需要与原始二进制发布相同的拥有权、可追踪性和批准逻辑。否则,您已经创建了一个足以让事件通过的盲点。
__CAPGO_KEEP_0__
从清单转为文化
团队通常将应用漏洞扫描作为清单项。安装扫描器。 在 CI 中运行它。导出报告以供审计。 这是起步的好地方,但一旦您的架构变得更加分布式,一旦您的发布频率加快,它就不再有效。
这种可持续的模型是文化和运营的。开发人员期望在 pull 请求中进行静态和依赖检查。 平台团队维护授权的扫描目标和容器覆盖。 安全团队调整策略、关联发现并将重要的发现与商业背景相关联。 发布团队将实时包和发布后更改视为首类 artifact,而不是非正式修复。
这种转变是将扫描转变为真正的风险减少。您停止测量活动并开始测量管道是否捕获了重要的内容、是否将其发送给了正确的所有者并在暴露之前修复它。
成熟的程序仍然有自己的意见。它阻止狭隘。它持续扫描。它优先考虑可利用性而不是噪音。它也不认为发布日是安全故事的结尾。
如果您部署 CapacitorJS 或 Electron 应用并需要一种实际的方法来关闭发布后修复的差距 Capgo 为 JavaScript、CSS、配置和资产修复提供了一个受控的实时更新路径,带有签名包、滚动频道、回滚保护和设备级观察性,自然融入现代漏洞管理工作流。