阶段 3 — 缓解
阶段 3 创建 CSD 缓解的前后对比证明。您先在无缓解措施的情况下重新运行攻击以建立基线,然后应用缓解措施,再次运行相同的攻击以证明 CSD 阻断了网络调用。在继续之前,阶段 2 必须已完成——所有 DET 检查均通过(PASS)。
步骤 1:确认无活跃缓解措施(基线)
Section titled “步骤 1:确认无活跃缓解措施(基线)”在捕获”之前”快照之前,验证环境是否干净——不应有任何活跃的缓解措施。这确保基线攻击在没有任何 CSD 阻断的情况下运行。
检查已缓解域名数量
Section titled “检查已缓解域名数量”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq '{count: (.items | length)}'如果数量不为 0,则存在来自先前运行的缓解措施。在继续之前删除每一条:
# 删除已缓解的域名(对每个域名重复执行)curl -s -X DELETE \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains/<domain-name>" \ | jq .将 <domain-name> 替换为缓解该域名时使用的 metadata.name(例如 cdn.jsdelivr.net、esm.sh、unpkg.com、ga.jspm.io、httpbin.org、jsonplaceholder.typicode.com)。如果 httpbin.org 清理后仍有残留项目,也请尝试删除 www.httpbin.org——某些先前的运行可能使用了该名称作为 metadata name。
确认阶段 2 的检测结果存在
Section titled “确认阶段 2 的检测结果存在”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'| 检查项 | 预期 | 状态 |
|---|---|---|
| 已缓解域名数量 | 0(干净基线) | 为 0 则 PASS,大于 0 则需要清理 |
| 已检测域名数量 | > 0(阶段 2 检测结果存在) | 大于 0 则 PASS |
| 数据外泄域名存在 | www.httpbin.org、jsonplaceholder.typicode.com | 至少出现一个则 PASS |
步骤 2:运行攻击——缓解前
Section titled “步骤 2:运行攻击——缓解前”在无缓解措施活跃的情况下重新运行组合模拟,以捕获新鲜的基线。这是**“之前”快照**——证明在未应用 CSD 缓解时攻击成功。
AI 自动化执行
Section titled “AI 自动化执行”具有浏览器自动化工具的 AI 助手使用与阶段 2 相同的 initScript(保存原生 fetch)以编程方式运行攻击模拟:
- 带 initScript 导航 — 首先导航至
about:blank以确保干净的文档上下文(避免先前导航遗留的过期 initScript),然后使用阶段 2 initScript(阶段 2 — AI 自动化执行 中的逐字代码)通过navigate_page导航至http://$F5XC_DOMAINNAME/#/login。此 initScript 保存原生setInterval、clearInterval、fetch和console.log——此处原生fetch引用是正确的,因为没有活跃的缓解措施 - 关闭欢迎横幅 — 使用
Escape键press_key关闭欢迎横幅。在后续访问中横幅可能不会出现(cookie 已持久化)。Cookie 同意对话框通过 Escape 键自动关闭 - 等待完成 — 等待 10 秒,让所有 CDN 脚本加载/错误回调和 fetch promise 解析完成
- 捕获证据 — 使用
list_console_messages检查[CSD Demo] Simulation complete和 CDN 加载结果;使用list_network_requests按script和fetch类型过滤,以验证 HTTP 状态码(200/201表示成功)
没有浏览器自动化工具的操作人员使用与阶段 2 — 步骤 8:攻击模拟相同的流程手动运行模拟:
- 导航至
http://xF5XC_DOMAINNAMEx/#/login - 在电子邮件和密码字段中输入虚拟凭据(不要提交)
- 打开开发者工具——按 F12 并切换至 Console 标签页
- 粘贴并运行触发检测中的组合检测脚本
- 观察控制台输出——所有 CDN 脚本应正常加载,数据外泄调用应以
200/201响应成功返回
证据——缓解前
Section titled “证据——缓解前”| 检查项 | 预期(缓解前) | 状态 |
|---|---|---|
| CDN 脚本注入 | 所有 4 个脚本标签加载——出现 [Supply Chain] Loaded from 消息,网络标签显示 200 | PASS |
向 www.httpbin.org 的数据外泄 fetch | 网络标签显示 200——数据已发送 | PASS |
| 向 jsonplaceholder.typicode.com 的数据外泄 fetch | 网络标签显示 201——数据已发送 | PASS |
| 控制台输出 | [CSD Demo] Simulation complete | PASS |
步骤 3:应用缓解措施
Section titled “步骤 3:应用缓解措施”对每个检测到的域名,向已缓解域名端点发送 POST 请求。阶段 2 模拟中的主要目标是 4 个 CDN 注入域名和任何检测到的数据外泄域名。
主要缓解目标(来自组合模拟脚本):
| 域名 | 角色 |
|---|---|
cdn.jsdelivr.net | CDN 脚本注入 |
esm.sh | CDN 脚本注入 |
unpkg.com | CDN 脚本注入 |
ga.jspm.io | CDN 脚本注入 |
www.httpbin.org | 数据外泄端点 |
jsonplaceholder.typicode.com | 数据外泄端点 |
缓解一个域名(每个域名运行一次):
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "name": "cdn.jsdelivr.net", "namespace": "xF5XC_NAMESPACEx" }, "spec": { "mitigated_domain": "cdn.jsdelivr.net" } }' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .对每个域名重复执行:
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"esm.sh","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"esm.sh"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# unpkg.comcurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"unpkg.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"unpkg.com"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# ga.jspm.iocurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"ga.jspm.io","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"ga.jspm.io"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# httpbin.org — 使用 www.httpbin.org 作为 mitigated_domain(见下方说明)curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"httpbin.org","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"www.httpbin.org"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# jsonplaceholder.typicode.comcurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"jsonplaceholder.typicode.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"jsonplaceholder.typicode.com"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .200 响应返回已创建的缓解域名对象。409 响应表示该域名已在缓解列表中——这是成功条件。
步骤 4:验证缓解措施已应用
Section titled “步骤 4:验证缓解措施已应用”列出所有已缓解域名,并确认数量与刚刚提交的域名数量匹配:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq '{count: (.items | length)}'| 检查项 | 预期 | 状态 |
|---|---|---|
| 已缓解域名数量 | 6(与 POST 数量匹配) | 数量匹配则 PASS |
步骤 3 的所有 POST 返回 200 或 409 | 每个域名均已接受 | PASS |
如果数量低于预期,请重新运行步骤 3 中缺失域名的 POST 命令。
步骤 5:运行攻击——缓解后
Section titled “步骤 5:运行攻击——缓解后”重新运行完全相同的组合模拟以捕获**“之后”快照**。模拟脚本完全相同——只有 CSD 的缓解状态发生了变化。来自已缓解域名的脚本加载现在被 CSD JavaScript 阻断(<script> 标签的 src 被清除为空字符串)。
AI 自动化执行
Section titled “AI 自动化执行”具有浏览器自动化工具的 AI 助手使用相同的阶段 2 initScript(阶段 2 — AI 自动化执行 中的逐字代码)以编程方式重新运行攻击模拟。initScript 保存原生 fetch 以避免 zone.js 错误——这不影响 CSD 缓解,因为 CSD 不拦截 fetch() 调用。
- 带 initScript 导航 — 使用带有
isolatedContext的new_page获取干净的浏览器上下文(避免步骤 2 遗留的过期 initScript),然后导航至about:blank,再使用阶段 2 initScript 导航至登录页面 - 关闭欢迎横幅 — 使用
Escape键press_key - 等待完成 — 等待 10 秒让所有异步回调完成
- 捕获证据 — 使用
list_console_messages检查[CSD Demo] Simulation complete;使用list_network_requests按script和fetch类型过滤,观察 CDN 脚本加载不存在(CSD 已清除脚本 src),而对数据外泄域名的 fetch 调用仍正常完成
没有浏览器自动化工具的操作人员使用与阶段 2 — 步骤 8:攻击模拟相同的流程手动重新运行模拟:
- 导航至
http://xF5XC_DOMAINNAMEx/#/login - 在电子邮件和密码字段中输入虚拟凭据(不要提交)
- 打开开发者工具——按 F12 并切换至 Console 标签页
- 粘贴并运行触发检测中的组合检测脚本
- 观察控制台和网络输出——已缓解域名的 CDN 脚本
onload和onerror回调不会触发(CSD 已将脚本src清除为空字符串,完全阻止了网络请求)。对数据外泄域名(www.httpbin.org、jsonplaceholder.typicode.com)的 Fetch 调用仍然完成,返回200/201——CSD 缓解阻断脚本加载,而非 fetch/XHR 调用
证据——缓解后
Section titled “证据——缓解后”| 检查项 | 预期(缓解后) | 状态 |
|---|---|---|
| CDN 脚本加载 | 已阻断 — 脚本不出现在网络标签中(CSD 已将 src 清除为空字符串) | PASS |
| CDN 脚本回调 | 已缓解域名的 onload 和 onerror 均不触发 | PASS |
向 www.httpbin.org 的数据外泄 fetch | 200 — fetch 仍然完成(CSD 不拦截 fetch) | INFO |
| 向 jsonplaceholder.typicode.com 的数据外泄 fetch | 201 — fetch 仍然完成(CSD 不拦截 fetch) | INFO |
| 控制台输出 | [CSD Demo] Simulation complete | PASS |
步骤 6:前后对比
Section titled “步骤 6:前后对比”这是演示的核心成果——并排证据证明,在同一页面上使用相同脚本发起的相同攻击,现在产生了完全不同的结果。
| 信号 | 缓解前(步骤 2) | 缓解后(步骤 5) |
|---|---|---|
| CDN 脚本加载 | 200 — 所有 4 个 CDN 脚本正常加载 | 已阻断 — 脚本不出现在网络标签中(CSD 已将 src 清除为空字符串) |
CDN onload 回调 | 出现 [Supply Chain] Loaded from 消息 | 无回调触发(未发出网络请求) |
向 www.httpbin.org 的数据外泄 | 200 — 数据已外泄 | 200 — fetch 仍然完成(CSD 不拦截 fetch) |
| 向 jsonplaceholder.typicode.com 的数据外泄 | 201 — 数据已外泄 | 201 — fetch 仍然完成(CSD 不拦截 fetch) |
| CSD 已缓解域名 API | 0 条已缓解 | 6 条已缓解 |
在后端数据中验证缓解措施
Section titled “在后端数据中验证缓解措施”每隔 60 秒查询一次 /detected_domains,最多查询 10 次(10 分钟)。查询返回后或 10 分钟上限到达后,继续进行对比表——这些检查仅供参考,不阻断阶段 4 的进行。
缓解后检查已检测域名:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'检查已缓解状态的脚本:
NOW=$(date +%s)START=$(( NOW - 86400 ))curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{\"startTime\": \"$START\", \"endTime\": \"$NOW\"}" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \ | jq '{total: (.scripts | length), scripts: [.scripts[]? | {script_name: .script_name, risk_level: .risk_level}]}'阶段 3 证据摘要
Section titled “阶段 3 证据摘要”| 检查项 | 预期 | 状态 |
|---|---|---|
| 基线干净(步骤 1) | 开始时 0 条已缓解域名 | PASS / FAIL |
| 之前——攻击成功(步骤 2) | 脚本加载,数据外泄返回 200/201 | PASS / FAIL |
| 缓解措施已应用(步骤 3) | 所有 6 个域名通过 POST 接受(200 或 409) | PASS / FAIL |
| 缓解数量已确认(步骤 4) | 列表中有 6 条 | PASS / FAIL |
| 之后——脚本加载已阻断(步骤 5) | CDN 脚本不出现在网络标签中,fetch 调用仍然完成 | PASS / FAIL |
| 前后对比(步骤 6) | 步骤 2 和步骤 5 的证据之间有明显差异 | PASS / FAIL |
阶段 3 完成。 准备好删除所有部署对象后,请前往阶段 4 — 清理。