周五傍晚,一款面向财务人员的 SaaS 产品在发布说明里加了两行不起眼的文字:“支持企业 SSO 登录”和“客户控制台加载更快”。第一行背后是新的身份提供商、解析其响应的代码,以及把外部账号与本地账号绑定的逻辑;第二行背后是在 CDN 上新增的一层缓存,挡在过去一直由应用服务器直接返回的页面前面。自动化测试全绿,用户满意,没有回归问题。年度渗透测试两个月前刚做完,下一次排在十个月以后。

这是一个假设的例子,但它提出的问题非常现实。如果缓存出错,把为一位客户生成的页面返回给另一位客户,会怎样?攻击者能否篡改身份提供商响应中的某个参数,把别人的企业账号绑定到自己的用户上?对已经改用 SSO 登录的用户来说,密码重置的行为有没有变化?这些问题都不一定会破坏产品宣称的功能。如果功能测试明确断言租户隔离、账号绑定和访问恢复等安全属性,它们可以发现问题;普通的顺利路径测试则可能漏掉。两个月前的渗透测试报告描述的,已经是一个不复存在的系统。

变更触发渗透测试正是为这种情况准备的。它的思路是:授权安全测试不仅按日历安排,也在系统发生实质性变化时启动——当权限、数据流、信任边界或不可信输入的处理方式发生改变时。下面讨论哪些变更真正值得人工测试、如何界定增量渗透测试的范围、如何把它嵌入交付流程、如何验收结果,以及应向服务商提出哪些问题。

为什么仅靠按日历安排的渗透测试有时不够

每年或每季度一次的计划性渗透测试很方便:预算可预期,覆盖面广,报告可以直接放进审计资料夹。它的弱点在于缺陷出现与被发现之间的时间差。如果团队每周发布一次,到下一次计划测试时,系统里会累积几十项变更,其中一部分恰恰触及安全的关键之处。

风险随着代码、配置和信任边界一起移动,测试也理应随之移动。但这种做法的目的并不是把每一次提交都变成一次付费渗透测试,而是把具体变更与它所影响的系统属性对应起来,并事先约定:哪些变更需要有针对性的人工检查,哪些由回归自动化覆盖,哪些可以安心等到下一次全面评估。

下文讨论的对象是 Web 应用、API 以及直接为其服务的基础设施。文中描述的任何测试,都以有权针对具体系统授权的一方出具书面授权、范围已经约定、测试规则已经成文为前提。本文不授予、也不暗示对任何系统进行测试的许可。

还有一点需要说明:公开标准中并没有一份统一的、强制性的“必须做渗透测试的变更”清单。下文的触发逻辑是实践建议,而不是监管要求,每个组织都应结合自己的发布节奏、数据和义务加以校准。

哪些变更会改变攻击面

面对任何变更,可以先问三个问题:谁能在系统中做什么,是否变了?哪些数据跨越哪条边界,是否变了?不可信输入的处理方式,是否变了?只要有一个问题的答案是“是”或“不确定”,这项变更就应进入分诊。

请注意这类变更的共同特征:改完之后功能照常可用。放宽的 CORS 策略、消失的 CSP 指令、Cookie 属性的新默认值、挡在已认证页面前的缓存——用户毫无察觉,“页面能打开”的测试也能通过。改变的不是功能,而是安全属性,这正是此类变更容易被放过的原因。

身份认证、会话与授权

HTTP 本身不在请求之间保存状态,但这并不意味着它没有会话。Cookie、令牌和服务端会话存储为它加上了状态,普通 Web 应用完全可以在服务端保存会话。因此,凡是改变这种状态如何创建、传递、续期和撤销的变更,都是触发候选:新的身份提供商、切换到 SSO、MFA 流程调整、令牌格式变化、新的 Cookie 属性、会话有效期变化以及登出逻辑修改。

授权需要单独关注:新增角色、带有独立访问权限的新对象类型、重写的资源归属校验。扫描器很难发现这类缺陷,因为请求在形式上完全合法,只是由错误的用户发出。如何系统地测试这类场景,可参阅我们关于业务逻辑安全测试的文章。

不要把人员身份认证与服务凭据混为一谈。为员工调整 MFA,与更换某个微服务调用另一个微服务所用的密钥,是风险不同、测试方法也不同的两类变更,即使工单里都写着“认证改进”。

安全响应头与浏览器策略

Content Security Policy、CORS、Cross-Origin Resource Policy 和 Permissions Policy,是应用告诉浏览器该信任什么的机制。修改它们往往是为了集成:加了支付组件、接入了分析服务、为另一个域名上的新前端开放了 API。“临时”允许任意来源,或者把收到的任何 Origin 原样返回,比弄清请求为何失败要省事——而这样的决定往往会长期保留下来。

请求路径上的基础设施

新的代理、缓存、负载均衡器或 CDN,以及协议变化——例如把连接升级为 WebSocket——都会改变请求如何到达应用、响应如何返回用户。重定向和缓存在这里尤其敏感。缓存键出错可能把个人页面交给陌生人;代理也可能以自己的方式解释应用在做访问决策时所依赖的请求头。WebSocket 连接建立后按自己的规则运行,过去对每个 HTTP 请求执行的检查,在其中可能根本不存在。

拼接命令、路径和标记的代码

用用户输入拼接操作系统命令、数据库查询、文件路径或 HTML 的代码,天然适合人工检查。这些弱点类别在 CWE Top 25 中位置突出;CISA 在其 Secure by Design 系列材料中,也专门呼吁厂商把跨站脚本、操作系统命令注入和目录遍历作为整类缺陷加以消除。新的文件上传和下载功能、基于模板的报表生成、从外部格式导入数据,都是此类缺陷容易出现的地方。

依赖、平台、集成与租户

框架或平台的大版本升级、迁移到另一个托管环境、合并租户、数据存储或信任域、接入新的第三方服务——这类变更之后,移动的不是某一个功能,而是安全所依赖的多个前提。新的对外端点和 API,尤其是管理类接口,应当被视为独立的攻击面;如何有条理地测试它们,可参阅我们的 REST API 安全评估指南。

哪些变更不必交给人工测试

触发清单的目的不是什么都测,而是把专家时间花在回报最高的地方。界面的外观调整、内容更新、不改变数据流的重构、不改变行为的小版本依赖更新,通常由静态分析、依赖扫描、流水线中的动态扫描和代码评审覆盖即可。

这里有一个陷阱。工单里的“重构”有时意味着把权限校验从一层挪到另一层,“小版本库更新”也可能意味着某个解析器的默认行为变了。因此,判定某项变更无需人工检查的人,应当是带着上一节的问题看过差异(diff)的人,而不是只读了工单标题的人。

把决策整理成分级会很方便。下面是一个建议模型,应当用自己的数据加以校准。

左右滑动查看对照

级别哪些变更怎么做用什么证明
0 级:仅自动化数据流、信任边界和安全控制不变:界面、内容、无新数据路径的重构静态分析、依赖扫描、流水线中的动态扫描流水线运行成功,差异评审中带有安全影响标记
1 级:定向审查单个组件中输入处理或配置的有限变化安全评审,以及与受影响要求对应的部分测试用例已执行检查的清单,附带带版本号的要求标识符
2 级:增量渗透测试身份认证、授权、会话、安全响应头、对外 API、请求路径上的基础设施对变更组件及其最近关联进行授权的人工测试,随后复测包含范围、环境、发现项和复测结果的报告
3 级:全面重新评估架构变化、新的信任域、平台迁移,或自上次基线评估以来累积的增量按新范围开展全面渗透测试新的基线,后续增量以它为参照

敏感数据、互联网可达性,以及 CWE Top 25 或 MITRE 基于 KEV 的弱点分析所强调的适用弱点类别,都是决定是否把变更上调一级时可以使用的信号。CWE 排名只是输入之一;所需测试深度还取决于可达攻击路径、潜在影响、现有控制和证据质量。只有当过去的评估范围足够广且具有代表性、未发现相关问题、测试质量与覆盖情况清楚,并且补偿性自动化控制已证明有效时,才应下调某类触发。如何把这些信号转化为工作顺序,可参阅我们关于基于风险的漏洞优先级排序的文章。

如何界定增量渗透测试的范围

一个危险的错误,是把增量理解为“改动过的文件列表”。增量是变更的组件,加上它们与未变部分之间最近的交互。回到前面的假设例子。新的 SSO 也许实现得很严谨,但它旁边还运行着旧机制:密码重置、修改邮箱、邀请用户加入组织、切换前签发的 API 令牌。如果只测新的登录流程,就会留下一个没有答案的问题:拥有本地密码的用户,能否通过某个旧端点绕过强制 SSO?

因此,界定范围时可以依次梳理三层。第一层是变更本身:新的端点、参数、角色、响应头和配置。第二层是相邻机制:信任这个变更组件、或者被它依赖的那些部分。第三层是变更可能打破的前提:过去由架构保证、现在只能由代码保证的东西。

对同一个例子中的缓存,范围则完全不同:哪些响应会被缓存,缓存键由什么构成,Cookie 和 Authorization 请求头如何被考虑,错误响应和重定向如何处理,能否诱使缓存保存原本属于另一位用户的响应。这不是对整个应用的大规模渗透测试,但也绝不只是检查一下 Cache-Control 响应头。

测试用例的内容可以取自 OWASP Web Security Testing Guide:增量测试只挑选与变更相符的类别。Cookie 处理变了,就做会话管理测试;CSP 变了,就做客户端测试;接入新的身份提供商,就做认证和授权测试。为一项变更跑完整本指南没有意义。

要求可以用 OWASP ASVS 来标注。ASVS 的要求带有 v5.0.0-1.2.5 这样的版本化标识符,OWASP 明确提醒,标识符在不同版本之间可能变化,因此报告中必须写明标注所依据的版本。要求清单以 CSV 和 JSON 等机器可读格式发布,所以“变更—要求—检查”之间的关联可以部分自动化。需要记住,这种标注说明检查了哪些要求,但本身并不能证明系统符合该标准。

如果组织采用假定失陷(assume breach)方式开展评估,增量测试可以有一个约定好的起点,例如某个租户中的普通用户账号。但报告必须明确写出:测试从事先约定的已失陷状态开始,并不能证明这种初始访问在现实中确实能够获得。

如果你即将发布包含 2 级变更的版本,又不清楚增量的边界在哪里,可以和 Pentest.red 团队具体梳理:哪些组件在变、哪些相邻机制信任它们、在哪个环境中测试是可以接受的、最终需要哪些证据。一个方便的起点是渗透测试范围说明表。

标准是共同语言,而不是仪式

NIST SP 800-115 是 2008 年发布的安全测试技术指南,涵盖测试规划、实施、发现项分析以及缓解策略制定,并在形式上把评估分为规划、执行和执行后三个阶段。它的发布远早于现代 CI/CD 流水线,但其逻辑与变更触发模式十分契合:规划变成界定增量,执行聚焦于变更组件,执行后阶段负责分析与建议。在这些阶段之外,许多团队还运行自己的“发现—修复—复测—关闭”工作循环;这是一种实践,并非 NIST 本身的表述。该文档还强调每种技术都有优点和局限——这提醒我们要针对具体环境选择技术,避免可能影响可用性的操作。

OWASP Top 10 和 CWE Top 25 可以作为优先级排序的输入之一:当变更触及某些弱点类别时,它们提示哪些类别值得考虑。单凭排名并不能决定所需的测试深度。把某个发现项归入某个 CWE 类别,只是描述缺陷的性质,并不意味着这个具体漏洞已被任何人利用——那需要另外的证据。

整个机制中隐含的要求是版本纪律。参考标准会更新:OWASP Top 10 有 2017、2021 和 2025 等版本,ASVS 的标识符会变化,WSTG 也会发布新版本。如果想把本季度的增量测试与去年的结果对比,每份报告都必须写明所用参考标准的版本,例如在该次测试时采用的 WSTG 4.2、ASVS 5.0.0 和 OWASP Top 10 2025。其中任何一项发布新版本时,都应重新审视分级模型以及测试与要求之间的映射。

权衡:增量测试与日历测试

变更触发方式的主要优势是相关性。测试人员把时间花在真正发生变化的地方,发现项出现时,做出变更的工程师对上下文还记忆犹新。第二个优势是可证明性:每一次重要发布都有自己的测试记录。

主要风险是盲区和过载。纯增量方式可能漏掉无人改动的组件中的漏洞,漏掉多项各自看似无害的变更之间的相互作用,也可能漏掉根本没有经过正式变更流程的配置漂移——比如有人手工改了负载均衡器上的一条规则。节奏很快的团队还可能产生超出预算承受能力的触发数量。

只按日历的方式预算可预期、覆盖面广,但发现项可能比发布滞后几个月。只按变更的方式精准及时,却可能漏掉基线漂移和跨组件问题。如果组织需要同时处理这两类盲区,混合模式是一种选择:定期的全面评估建立并刷新基线,增量测试覆盖两次基线评估之间的重要变更,自动化检查处理预先定义的可重复场景。具体比例取决于发布频率、数据敏感度、合同义务和已有证据,不存在通用的配比。

也应坦率承认一个局限:本文审阅的资料中没有对变更触发测试与计划性测试的有效性或成本作定量比较。这是一个合理的假设,值得在自己的项目中验证,例如跟踪每次增量测试在变更组件中产生了多少发现项。

如何把变更触发渗透测试嵌入交付流程

落地的起点不是测试团队,而是变更管理。在 pull request 或变更申请模板中加入一个安全影响字段:这项变更是否涉及身份认证、授权、会话、输入处理、安全响应头、对外接口、服务凭据或请求路径上的基础设施?只要有一项回答“是”,变更就进入分诊。如何检查这些控制点在流水线中真正生效、而不只是停留在纸面上,可参阅我们的 DevSecOps 安全评估指南。

一项变更如何变成一次测试:从工单到关闭的发现项
  1. 工单标记变更作者回答该变更是否涉及权限、会话、输入、响应头、对外接口或请求路径。
  2. 分诊与定级安全负责人查看差异,在 0 到 3 级之间定级,并记录决定及其理由。
  3. 范围与规则对 2 级和 3 级变更,约定增量、相邻机制、环境、时间、联系人和停止条件。
  4. 测试与分析测试人员检查变更组件及其关联,发现项按受影响的要求进行标注。
  5. 复测与关联在约定环境中复测修复,并把发现项与引入它的变更关联起来。

分诊是一个必须留下痕迹的决定。如果某项变更被定为 0 级,工单里应记录是谁、出于什么理由做出这个判断。

执行必须遵守授权要求。增量测试通常在约定的、尽可能接近生产的测试环境中进行,并依照书面测试规则执行,规则中写明范围、时间、联系人和停止条件。授权必须来自有权针对具体系统授权的一方,包括由第三方托管的服务:云服务商、SaaS 平台、外部支付网关。服务商绝不应默认自己已获授权。

测试环境是一种折中。在其中得到的结果不能不加说明地套用到生产环境:缓存配置、WAF 规则、服务版本和集成组合都可能不同。如果这些差异对所测变更有实质影响,应在报告中写明,并就部分安全的检查——例如响应头和浏览器策略——单独约定在生产环境中执行。

测试日志同样需要注意。日志中不应以明文保留令牌、密码和密钥,敏感数据应尽量减少,日志的访问权限和保留期限也应事先限制并约定。

复测与关闭证据

只有当发现项被修复、复测,并与引入它的变更关联起来,这个循环才算闭合。复测不是“开发说已经修好了”,而是重新执行攻击场景及其合理变体。如果发现项是 redirect_uri 参数未经校验,修复后不仅要测原始值,还要测子域名、其他编码方式、多余的斜杠,以及其他能绕过简单校验的变体。

复测结论仅限于实际测试过的环境和变体。如果不写明环境、构建版本和已测变体,“漏洞已消除”这一说法承诺的内容就超出了已确认的范围。关于如何开展这类检查,可参阅我们关于渗透测试修复验证的文章。

左右滑动查看对照

产物应包含的内容验收时如何检查警示信号
分诊记录变更内容、所定级别、决策人及理由抽查若干 0 级变更,与其差异对照涉及会话或权限的变更被定为 0 级
范围定义变更组件、相邻机制、环境、排除项、起始状态确认相邻机制被明确列出,而不是默认包含范围等同于改动文件列表
增量测试报告参考标准版本、已执行检查、带复现步骤的发现项、测试环境与生产的差异按报告描述复现一到两个发现项未写明环境和版本,发现项没有复现步骤
复测结果构建版本、环境、已测绕过变体、最终状态检查“已关闭”状态是否对应具体构建和变体仅凭开发口头说明标记“已修复”,未重新测试

随着时间推移,这些记录会产生特定于本项目的数据,而公开资料无法提供这些数据:每类触发带来多少发现项、修复速度如何,以及哪些触发需要复核。发现项较少,只有在测试足够广泛且执行质量可靠、发布具有代表性、补偿性控制持续有效时,才支持下调级别。

如何选择增量渗透测试服务商

内部的触发与分级模型成形后,采购通常更容易得到可比的结果。没有这套模型,第一次服务还必须定义变更如何进入范围,各次发布的结果也会更难比较。服务商对这类服务的称呼各不相同:持续渗透测试、渗透测试即服务(PTaaS)、按需复测。名称并不重要,重要的是能否一致地、以可追溯的方法测试给定增量,并满足双方实际约定的响应时间。

CISA 的 Secure by Demand 指南是为正在进行采购谈判的软件客户编写的,它的核心立场同样适用于采购测试服务:要证据,不要承诺。落到实处,就是几个问题。测试对应哪个版本的 WSTG 和 ASVS,报告是否引用带版本号的标识符?服务商如何界定增量,又如何考虑与未变组件的交互?从触发到测试可以约定多长时间,紧急的发布前检查如何安排?是否包含修复复测,如何确认发现项已关闭?每个项目的测试规则、范围审批和停止条件如何形成书面文件?如何利用 CWE Top 25、基于 KEV 的弱点列表或 OWASP Top 10 来聚焦工作?结果能否以结构化格式导出,并与变更记录关联?哪些是自动化完成的,哪些由专家完成,服务商自己声明了哪些局限?

需要警惕的是:承诺仅靠自动化就能全面覆盖;无法解释参考标准版本更替时如何保持结果可比;在没有为所有受影响环境办妥书面授权的情况下就愿意开始测试。还要记住,渗透测试不是认证、不是合规评定,也不是鉴证意见。它说明在约定的范围、环境和时间内找到了什么、没有找到什么,并不保证不存在漏洞。渗透测试报告可以作为更广泛符合性评估的一项证据,但正式的符合性评估仍是另一项工作,应由具备适当资质的机构或审计方完成。

如果你正在搭建混合模式,可以和 Pentest.red 讨论基线评估可能是什么样子,以及哪些变更适合纳入增量测试:你的内部流程需要哪些证据,哪些环境可用于测试,组织中由谁签署授权。我们的渗透测试服务说明和范围说明表可以帮助你为这次沟通做好准备。

结语

变更触发渗透测试把安全测试与风险状况发生变化的时刻联系起来:权限变了,数据跨越了新的边界,不可信输入有了新的通路。它可以补充定期的基线评估和自动化回归检查;无论采用哪种运行模式,都需要与具体系统属性挂钩的触发分级、带版本号的参考标准,以及结论边界清晰的复测。

本文审阅的资料并不能证明这种方式总是更便宜或更有效——这需要在自己的项目中衡量。但它提供了一种可验证的方式,让测试跟上交付节奏,并回答任何细心阅读你们发布说明的人迟早会问的问题:这项变更,有人测过吗?

PENTEST.RED

讨论渗透测试范围与报价

首先明确系统、访问权限、限制条件和预期证据。

准备测试范围

本文以深入研究为基础,经过编辑整理,注重清晰表达和实际应用。

PENTEST.RED / RED JOURNAL