From 64abe12889fb6c3888d470d79d85c6491e8051b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Thu, 16 Jul 2026 11:30:34 +0800 Subject: [PATCH] Add files via upload --- .../cyberstrikeai-browser-extension/README.md | 4 +- .../README.zh-CN.md | 9 +++- .../dist/cyberstrikeai-browser-extension.zip | Bin 61459 -> 62611 bytes .../lib/api.js | 8 +++- .../lib/storage.js | 28 +++++++---- .../manifest.json | 2 +- .../panel/panel.js | 44 +++++++++++------- 7 files changed, 64 insertions(+), 31 deletions(-) diff --git a/plugins/browser-extension/cyberstrikeai-browser-extension/README.md b/plugins/browser-extension/cyberstrikeai-browser-extension/README.md index 661079ef..bcd0b474 100644 --- a/plugins/browser-extension/cyberstrikeai-browser-extension/README.md +++ b/plugins/browser-extension/cyberstrikeai-browser-extension/README.md @@ -1,6 +1,6 @@ ## CyberStrikeAI Browser Extension -**Version 0.3.8** — Full docs: **README.zh-CN.md** +**Version 0.3.10** — Full docs: **README.zh-CN.md** Chromium DevTools extension: capture Network traffic and send it to CyberStrikeAI for AI-assisted security testing. Aligned with the Burp Suite plugin. @@ -51,7 +51,7 @@ Closing DevTools clears panel data. Closing the browser invalidates the session After reloading the extension, close DevTools completely and reopen (F12) if you see `chrome.runtime.connect` errors — the old panel context is invalidated. -If Validate reports `cross-origin request denied`, upgrade and restart the CyberStrikeAI server. Current versions recognize valid Chrome/Edge extension origins automatically, so no extension ID or CORS configuration is required. The browser will still request host access on the first Validate. +If Validate reports `cross-origin request denied`, upgrade and restart the CyberStrikeAI server. Current versions recognize valid Chrome/Edge extension origins automatically, so no extension ID or CORS configuration is required. The browser requests access only to the configured server origin on the first Validate, directly from the Validate click so Chromium can reliably show the optional-permission prompt. ### Package diff --git a/plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md b/plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md index e695ad4d..d49c22f6 100644 --- a/plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md +++ b/plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md @@ -1,6 +1,6 @@ ## CyberStrikeAI 浏览器扩展 -**当前版本:0.3.8**(UI 为英文;中文说明见下文) +**当前版本:0.3.10**(UI 为英文;中文说明见下文) Chrome / Edge(Chromium)DevTools 扩展:在开发者工具中捕获 **Network** 流量,发送到 CyberStrikeAI 进行 AI 辅助安全测试。能力与 Burp Suite 插件对齐,并按生产场景做了性能与体验优化。 @@ -88,6 +88,7 @@ Cookie: ... - **401/403** 时自动清空 Token 并展开连接栏 - Send 前主动校验 Token 有效性 - **optional_host_permissions**:Validate 时按需授权 +- 权限申请直接绑定 Validate 点击事件,仅申请当前 CyberStrikeAI 服务 origin;已授权地址不会重复弹窗 --- @@ -161,6 +162,12 @@ HTTP/2 伪首部。展示与 AI Prompt 已归一化为 HTTP/1.1;原始 HAR 仍 **Validate 显示 `cross-origin request denied`?** 升级并重启 CyberStrikeAI 服务。新版服务会自动识别格式合法的 Chrome/Edge 扩展 Origin,无需复制插件 ID 或配置 CORS 白名单;插件首次 Validate 时仍会请求访问目标服务地址的浏览器权限。 +**Validate 要求允许访问 CyberStrikeAI 服务?** +在浏览器弹出的权限框中允许访问当前服务地址。插件只按需申请所填写的服务 origin,不需要开启全站访问。如果未出现权限框,请在 `chrome://extensions/` 重新加载扩展,完全关闭 DevTools 后再打开并点击 Validate。 + +**HTTPS 显示无法连接,但 Burp 正常?** +Burp 插件会信任自签名证书,浏览器扩展不能绕过 Chromium 的 TLS 校验。请先在浏览器中打开服务地址并信任证书;生产环境建议使用包含服务 IP/域名 SAN 的受信任证书。 + **Test History 很多会挡住 Captured Requests 吗?** 不会。历史区最高占侧边栏 **42%**,超出部分区域内滚动;捕获区占剩余空间。 diff --git a/plugins/browser-extension/cyberstrikeai-browser-extension/dist/cyberstrikeai-browser-extension.zip b/plugins/browser-extension/cyberstrikeai-browser-extension/dist/cyberstrikeai-browser-extension.zip index f9f83fb56efbe1adc614b111720bdbe04f8494a9..c2bf4ff953d8969f528cd047bb03e0234520d50d 100644 GIT binary patch delta 20759 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 Yb=w)1 { + if (granted) return; + const err = new Error(`Allow extension access to ${new URL(baseUrl).origin} to continue`); + err.code = 'HOST_PERMISSION_DENIED'; + throw err; + }); } diff --git a/plugins/browser-extension/cyberstrikeai-browser-extension/manifest.json b/plugins/browser-extension/cyberstrikeai-browser-extension/manifest.json index afcd1dc6..b05e3f71 100644 --- a/plugins/browser-extension/cyberstrikeai-browser-extension/manifest.json +++ b/plugins/browser-extension/cyberstrikeai-browser-extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "CyberStrikeAI", - "version": "0.3.9", + "version": "0.3.10", "description": "Capture browser HTTP traffic and send to CyberStrikeAI for AI-assisted security testing.", "devtools_page": "devtools.html", "permissions": ["storage"], diff --git a/plugins/browser-extension/cyberstrikeai-browser-extension/panel/panel.js b/plugins/browser-extension/cyberstrikeai-browser-extension/panel/panel.js index 62188d62..a2ba06ce 100644 --- a/plugins/browser-extension/cyberstrikeai-browser-extension/panel/panel.js +++ b/plugins/browser-extension/cyberstrikeai-browser-extension/panel/panel.js @@ -678,19 +678,23 @@ async function initConfig() { async function persistConnection() { try { - await saveConfig({ - host: $('host').value.trim(), - port: $('port').value.trim(), - https: $('https').checked, - filterApiOnly: $('filter-api').checked, - renderMarkdown: $('render-md').checked, - showDebugEvents: $('debug-events').checked, - }); + await saveConfig(connectionConfigFromForm()); } catch (err) { onContextLoss(err); } } +function connectionConfigFromForm() { + return { + host: $('host').value.trim(), + port: $('port').value.trim(), + https: $('https').checked, + filterApiOnly: $('filter-api').checked, + renderMarkdown: $('render-md').checked, + showDebugEvents: $('debug-events').checked, + }; +} + async function onValidate() { if (validating) { validateAbort?.abort(); @@ -703,17 +707,23 @@ async function onValidate() { validateAbort = new AbortController(); $('btn-validate').textContent = 'Cancel'; setStatus('Validating...', 'pending'); - await persistConnection(); - try { - config = await loadConfig(); - } catch (err) { - if (onContextLoss(err)) return; - throw err; - } - const baseUrl = baseUrlFrom(config); + + const nextConfig = connectionConfigFromForm(); + const baseUrl = baseUrlFrom(nextConfig); const password = $('password').value; + let hostPermission; try { - await ensureHostPermission(baseUrl); + // Invoke before the first await so Chrome still associates the optional + // permission prompt with the Validate button's user gesture. + hostPermission = ensureHostPermission(baseUrl); + } catch (err) { + hostPermission = Promise.reject(err); + } + + try { + await hostPermission; + await saveConfig(nextConfig); + config = { ...config, ...nextConfig }; const auth = await loginAndValidate(baseUrl, password, validateAbort.signal); token = auth.token; tokenExpiresAt = auth.expiresAt || '';