CyberStrikeAI 浏览器扩展实战:在 DevTools 中捕获 Network 流量并驱动 AI 安全测试
【免费下载链接】CyberStrikeAIThe system of action for AI-native cybersecurity—where intent becomes governed execution, evidence becomes operational memory, and every operation improves the next.项目地址: https://gitcode.com/GitHub_Trending/cy/CyberStrikeAI
CyberStrikeAI 官方提供了一个 Chrome / Edge(Chromium)DevTools 扩展,它直接在开发者工具中捕获 Network 流量,把真实的 HTTP 请求发送到 CyberStrikeAI 服务端进行 AI 辅助安全测试。本文基于仓库中的 中文说明文档(当前版本 0.3.10)与扩展源码逐节展开:从安装到捕获管线、HTTP 归一化、AI 发送与 SSE 流式输出、Token 会话安全,再到内存上限、性能取舍、打包发布与常见问题排查,读完你可以完整上手这个扩展,并理解它与 Burp Suite 插件在能力上的对齐关系。
一、扩展定位:DevTools 里的 AI 渗透测试入口
该扩展的核心工作流可以概括为一句话:在开发者工具中捕获 Network 流量 → 发送到 CyberStrikeAI 进行 AI 辅助安全测试。官方文档明确说明,其能力与 Burp Suite 插件对齐,并按生产场景做了性能与体验优化。与 Burp 插件最大的差异在于流量来源:Burp 插件读取 Proxy 历史,而浏览器扩展直接监听 DevTools Network 面板背后的chrome.devtools.network事件。
| 能力 | Burp 插件 | 浏览器扩展 |
|---|---|---|
| 流量来源 | Proxy 历史 | DevTools Network |
| 连接配置 | Tab 内 | Tab 内(可折叠) |
| HTTP 格式 | HTTP/1.1 | 展示/Prompt 归一化为 HTTP/1.1 |
| 项目/角色/模式 | Send 弹窗 | Send 弹窗 |
| SSE 输出 | Progress + Final | Progress + Final |
| 捕获开关 | — | ● 捕获中 / ○ 已暂停 |
二、快速开始
安装与首次连接只需 5 步(UI 为英文,中文说明见官方文档):
- 打开
chrome://extensions/→ 开启开发者模式→ 点击加载已解压的扩展程序; - 选择目录:
plugins/browser-extension/cyberstrikeai-browser-extension/; - 打开目标页面 → 按F12→ 点击 DevTools 顶部新增的CyberStrikeAITab;
- 填写 Host / Port / Password → 点击Validate(首次会请求访问服务器地址的浏览器权限);
- 在左侧选中捕获到的请求 →Send→ 在Output区查看 AI 流式结果。
点击浏览器工具栏图标只能查看只读连接状态;完整配置与操作均在 DevTools 面板内完成。这一"Popup 只读 + DevTools 主工作区"的分工是有意为之——不在 Popup 中重复完整配置表单,避免与主流程脱节:
| 位置 | 用途 |
|---|---|
| DevTools 面板 | 连接、Validate、捕获、Send、Output(主工作区) |
| 扩展 Popup | 只读连接状态 + 版本号 + 打开 DevTools 引导 |
三、MV3 架构:manifest 声明了哪些能力
从 manifest.json 可以看到这是一个标准的 Manifest V3 扩展,版本 0.3.10,关键声明如下:
"devtools_page": "devtools.html":使扩展能在 DevTools 中注册自定义面板;"permissions": ["storage"]:仅申请存储权限;"optional_host_permissions": ["http://*/*", "https://*/*"]:按需(optional)的主机权限——这是后文 Validate 时会弹出"允许访问服务地址"权限框的原因,且插件只申请当前所填写的 CyberStrikeAI 服务 origin,无需开启全站访问;"background": { "service_worker": "background/service-worker.js" }:MV3 以 Service Worker 作为后台中枢;"action": { "default_popup": "popup/popup.html" }:工具栏图标挂载只读状态 Popup。
目录结构(与 官方文档 一致):
manifest.json # MV3 清单 background/service-worker.js # 捕获队列、Panel Port、全局开关 devtools.js # Network 监听(最早过滤) devtools.html panel/ panel.html / panel.js / panel.css # 主 UI popup/ popup.html / popup.js / popup.css # 只读状态 lib/ auth-session.js # Token 过期检测与剩余时间提示 api.js # 登录、SSE、项目/角色 API storage.js # 配置 + session token + expires_at capture.js # HAR 摘要、静态过滤 http-normalize.js # HTTP/2 → HTTP/1.1 展示/Prompt formatter.js # toPrompt 组装 markdown.js # Final Markdown 渲染 catalog-cache.js # 项目/角色 5 分钟缓存 constants.js # 上限常量 icons/ # 16 / 48 / 128 package.sh四、流量捕获管线:devtools → service-worker → panel
捕获数据流为:devtools.js监听 Network →background/service-worker.js维护每 Tab 队列 → Panel 通过 Port 订阅。这条链路上有三层过滤,是"高流量 SPA 下不拖慢网页"的关键。
4.1 devtools.js:最早的预过滤
devtools.js 通过chrome.devtools.network.onRequestFinished监听请求完成事件。源码中可以看到几个关键设计:
- 内存标志位:
filterApiOnly与captureEnabled直接存于内存(let filterApiOnly = true; let captureEnabled = true;),注释写明"In-memory flags — avoids storage read on every network request",即每个网络请求到达时都不读 storage,只通过chrome.storage.onChanged监听和运行时消息(set-filter-api/set-capture-enabled)同步; - 预过滤优先:调用
mightCaptureRequest(url, resourceType, filterApiOnly),命中的静态资源在读取响应体(request.getContent)之前就被丢弃——这是官方文档中"静态资源 URL / MIME 预过滤,命中前不读响应体"的源码依据; - 过滤通过后,用
summarizeHarEntry(request, body, resourceType)生成摘要 entry,再以capture-entry消息发给 Background。
4.2 过滤规则:XHR/Fetch only 与静态资源黑名单
capture.js 中的mightCaptureRequest定义了两种模式:
- filterApiOnly(默认开启,即"XHR/Fetch only"开关):只放行
xhr、fetch、websocket三类资源,即只捕获 API 类请求; - 关闭 XHR only 时:仍会过滤
static类型资源与静态扩展名 URL(js/css/png/jpe?g/gif/svg/webp/ico/woff2?/ttf/eot/map/wasm),以及 MIME 前缀为image/、font/、audio/、video/、text/css的响应。
4.3 service-worker.js:每 Tab 队列与订阅广播
service-worker.js 是捕获中枢,从源码可以看到:
capturesByTab(Map)维护每个 Tab 独立的捕获列表,新条目list.unshift(entry)插入队首,trimCaptures把长度钳制在 200 条以内(超出丢弃最旧);- Panel 通过
chrome.runtime.connect建立名为cyberstrike-panel的 Port 并发送subscribe消息,Worker 先回推该 Tab 的历史全量列表({ type: 'list', entries }),之后每条新捕获经broadcastTab增量推送; cleanupOldTabs保证同时最多保留20 个 Tab 的捕获槽,超限时丢弃非当前 Tab 的数据;get-latest-api消息实现了Latest XHR按钮的底层逻辑:在当前 Tab 列表中find第一条resourceType为xhr或fetch的条目。
4.4 单条截断与摘要结构
summarizeHarEntry生成列表所需的摘要对象(title形如GET /api/foo),并在入库时就截断:请求体64KB(MAX_REQUEST_BODY: 65536)、响应体4KB(MAX_RESPONSE_BODY: 4096),超长部分以… [truncated]结尾。注意原始 HAR(含 HTTP/2 伪首部)仍保存在内存 entry 中,仅展示与 Prompt 使用归一化版本。
五、HTTP 展示与 AI Prompt:HTTP/2 到 HTTP/1.1 的归一化
浏览器在 HTTPS 下走 HTTP/2 时,DevTools 捕获到的 HAR 里带有:method、:path、:authority、:status等伪首部。http-normalize.js 负责把它们翻译回经典的 HTTP/1.1 格式(与 Burp 插件输出一致),且从不修改存储中的原始 HAR:
normalizeRequestBlock:解析:method/:path/:authority,若原头部中没有Host行则从伪首部或 URL 中补齐,输出GET /api/foo HTTP/1.1\nHost: example.com\nCookie: ...形式;normalizeResponseBlock:读取:status输出HTTP/1.1 200状态行 + 常规头。
formatter.js 的toPrompt则把归一化结果组装成发给 AI 的 Prompt,结构为:
<测试指令>(默认:Perform web penetration testing on this traffic and output results. Test only this endpoint; do not expand to other APIs.) [Target] GET https://example.com/api/foo [Request] GET /api/foo HTTP/1.1 Host: example.com ... [Optional: Response (truncated)] HTTP/1.1 200 ...默认指令来自 constants.js 的CSAI_DEFAULT_INSTRUCTION,其中"Test only this endpoint; do not expand to other APIs"明确把测试范围限定在单端点上,避免 AI 向其他 API 扩散。
六、发送到 CyberStrikeAI:四种 Agent 模式与 SSE 流
Send 弹窗通过动态 API拉取项目/角色列表——api.js 分别请求/api/projects?limit=500与/api/roles(结果有 5 分钟本地缓存,见lib/catalog-cache.js),用户在弹窗中选择项目 / 角色 / 对话模式并填写测试指令。
四种对话模式在源码中的定义直接映射到服务端 SSE 端点:
| 模式 | 端点 | 附加参数 |
|---|---|---|
| Eino Single (ADK) | POST /api/eino-agent/stream | — |
| Deep (DeepAgent) | POST /api/multi-agent/stream | orchestration: deep |
| Plan-Execute | POST /api/multi-agent/stream | orchestration: plan_execute |
| Supervisor | POST /api/multi-agent/stream | orchestration: supervisor |
streamTest以Accept: text/event-stream发起请求,用AbortController持有连接,按行解析data:前缀的 JSON 事件,type === 'done'时结束。Stop按钮做了双层中止:本地controller.abort()切断 SSE 连接,同时携带conversationId调用服务端POST /api/agent-loop/cancel,确保服务端 Agent 循环同步停止。
流式输出的截断策略
| 数据 | 上限 | 说明 |
|---|---|---|
| Progress 日志 | 512KB / run(MAX_PROGRESS_CHARS: 524288) | 超出截断 |
| Final Response(进行中的测试) | 不截断 | 当前 run 完整保留 |
| Final Response(历史 run) | 100KB 软截断(MAX_FINAL_ARCHIVE_CHARS: 100000) | 切换到其他 run 时执行 |
| Markdown 渲染 | 超100KB(MAX_MARKDOWN_CHARS: 100000)降级纯文本 | 流式阶段为纯文本,结束后经requestIdleCallback渲染 |
Copy按钮可复制当前的 Request / Response / Final。
七、安全与权限:Session Token、过期探测与服务端 CORS
7.1 Token 生命周期
从 auth-session.js 与官方文档可以看到完整的安全设计:
- Token 存于chrome.storage.session,关闭浏览器即失效(不写 local storage);
- 登录(
POST /api/auth/login,body 为{"password": ...})成功后保存expires_at,状态栏显示剩余时间(如OK · 11h 30m),剩余不足 30 分钟时提示expiring soon; - 不会自动续期(无 refresh token):过期后需重新 Validate(需 Password);
- 本地过期检测周期30s,同时每 30s 向服务端
GET /api/auth/validate探测(带Authorization: Bearer <token>);切回 DevTools 面板时立即探测一次; - 服务不可达时显示无法连接服务;重启服务后 session 被清空,Token 失效则显示服务已重启或 Token 已失效;
- 401/403时自动清空 Token 并展开连接栏,引导重新登录;Send 前还会主动校验 Token 有效性。
7.2 按需主机权限与 Origin 识别
- Validate 点击事件直接绑定
optional_host_permissions申请流程,浏览器权限框只针对当前所填写的 CyberStrikeAI 服务 origin;已授权地址不会重复弹窗。 - 服务端一侧同样做了配套:从 app.go 的
corsMiddleware源码看,服务端除了放行同源与操作员显式配置的 origin 外,还内置了 Chromium 扩展 origin 识别逻辑——isChromiumExtensionOrigin校验 scheme 为chrome-extension、extension ID 由 16 个 a–p 字符组成(Chrome/Edge 扩展 ID 的合法格式),并额外拒绝携带端口的 origin;不合法的跨域请求直接返回 403cross-origin request denied。cors_security_test.go 中的测试用例验证了合法扩展 origin 会被回显到Access-Control-Allow-Origin,而too-short等非法 ID 被拒绝。这意味着升级服务后无需复制插件 ID 或配置 CORS 白名单,插件 Validate 即可直连。
八、界面说明与按钮速查
┌─ 连接栏(Validate 成功后可收起)────────────────────────────┐ │ Logo │ https://host:port │ 连接设置 │ ● OK │ ├─ 操作栏 ────────────────────────────────────────────────────┤ │ Send │ Latest XHR │ Stop │ Copy │ Clear │ ●捕获中/○已暂停 │ │ XHR/Fetch only │ Debug │ Markdown │ ├──────────────┬──────────────────────────────────────────────┤ │ Test History │ Output │ Request │ Response │ │ Captured Req │ Progress + Final Response │ └──────────────┴──────────────────────────────────────────────┘| 区域 | 说明 |
|---|---|
| 连接栏 | Host、Port、HTTPS、Password、Validate;成功后收起为https://host:port摘要 |
| Test History | 最多 50 次 Send 记录,可回看 Progress / Final |
| Captured Requests | 当前 Tab 捕获列表,最多 200 条,支持搜索 |
| Output | 默认 Tab:流式 Progress + Final Response |
| Request / Response | 查看选中流量的 HTTP/1.1 格式原文 |
| 控件 | 作用 |
|---|---|
| Validate | 登录并校验 Token;进行中再次点击为 Cancel |
| 连接设置 / 收起 | 展开或折叠 Host/Port/Password 表单 |
| Send | 对选中捕获发起到 CyberStrikeAI |
| Latest XHR | 选中最近 XHR/Fetch 并 Send |
| Stop | 停止当前 AI 流(本地 + 服务端) |
| Clear Output | 清空当前 run 的 Progress / Final |
| ● 捕获中 / ○ 已暂停 | 启用或暂停 Network 捕获 |
| XHR/Fetch only | 只捕获 API 类请求 |
| Debug events | 在 Progress 显示更多 SSE 事件 |
| Markdown | Final 完成后渲染富文本 |
| Clear All | 清空 Test History |
| Clear | 清空当前 Tab 捕获列表 |
九、数据与内存上限:不会无限增长
所有内存数据都有硬上限,集中在 constants.js 的CSAI_LIMITS中:
| 数据 | 上限 | 位置 | 清理时机 |
|---|---|---|---|
| 捕获请求 | 200 条 / Tab | Background + Panel 内存 | 超出丢弃最旧;可手动 Clear |
| Tab 捕获槽 | 20 个 Tab | Background 内存 | 超出丢弃非当前 Tab |
| 测试历史 | 50 条 | Panel 内存 | 超出丢弃最旧;Clear All |
| Progress | 512KB / run | Panel 内存 | 超出截断 |
| Final(进行中) | 无硬上限 | Panel 内存 | — |
| Final(历史) | 100KB 软截断 | Panel 内存 | 切换到其他 run 时 |
| 配置 + Token | 极小 | chrome.storage | 手动改配置 |
三个天然回收点:关闭 DevTools→ Panel 内存清空;关闭浏览器→ Session Token 失效;Service Worker 被 Chrome 回收→ Background 捕获队列清空。
十、性能说明
| 场景 | 影响 |
|---|---|
| 未开 DevTools | 无影响(不监听 Network) |
| DevTools 开 + 捕获暂停 | 几乎无影响 |
| DevTools 开 + 捕获中 + XHR only | 仅匹配请求有轻微开销 |
| 高流量 SPA | 建议保持XHR/Fetch only,不需要时点已暂停 |
源码中对应的优化手段:过滤器标志内存化(避免每请求读 storage)、静态资源不读 body、捕获列表增量插入、搜索防抖、requestAnimationFrame节流流式 UI 更新。
十一、打包发布
在仓库根目录下执行:
bash plugins/browser-extension/cyberstrikeai-browser-extension/package.sh # → dist/cyberstrikeai-browser-extension.zippackage.sh 会把扩展目录zip -r打包(排除dist/、package.sh与.DS_Store)。图标由项目根 logo 图片 生成(macOS 使用 sips):
LOGO="images/logo.png" ICONS="plugins/browser-extension/cyberstrikeai-browser-extension/icons" for size in 16 48 128; do sips -z $size $size "$LOGO" --out "$ICONS/icon${size}.png" done十二、常见问题
扩展更新后报错chrome.runtime.connectundefined?扩展重载后旧 DevTools 面板上下文失效。请:关闭 DevTools → 重新加载扩展 → 再开 F12。
Token 过期会自动刷新吗?不会自动续期(无 refresh token)。插件保存expires_at、显示剩余时间,每 30s 向服务端校验,切回 DevTools 时立即校验。服务重启后 session 清空,需重新 Validate。
重启服务后状态还显示 OK?v0.3.7 起每 30s 探测/api/auth/validate;不可达显示黄色警告,Token 失效则清空并展开连接栏。重载扩展后请关闭 DevTools 再开 F12。
Request 里为什么曾经有:authority、:method?那是 HTTP/2 伪首部。展示与 AI Prompt 已归一化为 HTTP/1.1(见上文 http-normalize.js 的实现);原始 HAR 仍保存在内存 entry 中。
Console 里 localhost CORS 报错是插件造成的吗?不是。那是页面自身请求本机服务被浏览器拦截,与扩展无关。
Validate 显示cross-origin request denied?升级并重启 CyberStrikeAI 服务。新版服务会自动识别格式合法的 Chrome/Edge 扩展 Origin(internal/app/app.go的isChromiumExtensionOrigin),无需复制插件 ID 或配置 CORS 白名单;插件首次 Validate 时仍会请求访问目标服务地址的浏览器权限。
HTTPS 显示无法连接,但 Burp 正常?Burp 插件会信任自签名证书,浏览器扩展不能绕过 Chromium 的 TLS 校验。请先在浏览器中打开服务地址并信任证书;生产环境建议使用包含服务 IP/域名 SAN 的受信任证书。
Test History 很多会挡住 Captured Requests 吗?不会。历史区最高占侧边栏 42%,超出部分区域内滚动;捕获区占剩余空间。
会拖慢网页吗?日常浏览(不开 DevTools)无影响。调试时可用"已暂停"完全停止捕获。
十三、已知限制
- Chrome不提供Network 面板右键菜单 API → 扩展因此采用Latest XHR一键选中 + 自建捕获列表的方案;
- Firefox 需
about:debugging临时加载;storage.session不可用时 Token 回退到local存储; - 无法一键从 Popup 跳转到 DevTools 指定面板(Chrome API 限制)。
小结
CyberStrikeAI 浏览器扩展把"真实浏览器流量"直接接入了 AI 安全测试管线:MV3 三层结构(devtools 预过滤 → Service Worker 每 Tab 队列 → Panel 订阅)保证了高流量页面下的低开销;HTTP/2 到 HTTP/1.1 的归一化让 AI Prompt 与 Burp 插件输出保持一致;Session Token + 30s 探测 + 服务端扩展 Origin 识别构成了闭环的认证与 CORS 策略;全部内存数据都有明确上限与回收时机。对于希望在真实 Web 应用中边调试边做 AI 辅助渗透测试的场景,它提供了一条"DevTools 即 Proxy"的轻量路径。
【免费下载链接】CyberStrikeAIThe system of action for AI-native cybersecurity—where intent becomes governed execution, evidence becomes operational memory, and every operation improves the next.项目地址: https://gitcode.com/GitHub_Trending/cy/CyberStrikeAI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考