sebaxzero/pi-browser-search

GitHub: sebaxzero/pi-browser-search

为 pi AI 助手提供基于真实 Playwright 浏览器的网页搜索与交互能力,并内置提示注入净化与 SSRF 防护的安全扩展。

Stars: 0 | Forks: 0

# pi-browser-search [![测试](https://github.com/yuin/goldmark/actions?query=workflow:test](https://static.pigsec.cn/wp-content/uploads/repos/cas/96/96516d7a51f21139fae950e3129296fedeb5ab5f68f6a4dd1d280445b5bfdb15.svg)](https://github.com/sebaxzero/pi-browser-search/actions/workflows/test.yml) [![npm](https://img.shields.io/npm/v/pi-browser-search)](https://www.npmjs.com/package/pi-browser_search) 一个 [pi](https://pi.dev) 扩展,添加了由真实 Playwright Chromium 浏览器支持的 `browser_search`、`browser_open`、`browser_act` 和 `browser_read` 工具。 静态抓取无法处理 JavaScript 渲染的页面、SPA、Cookie 墙或懒加载内容。此扩展转而驱动真实的浏览器,同时强制执行与 [pi-safe-search](https://github.com/sebaxzero/pi-safe-search) 相同的纵深防御:对每个结果进行提示注入净化,并在网络层对浏览器发出的每个请求(不仅仅是模型请求的请求)强制执行 SSRF 保护。 ## 安装 从 npm 安装: ``` pi install npm:pi-browser-search ``` 或从 git 安装: ``` pi install git:github.com/sebaxzero/pi-browser-search.git ``` 在任一形式后添加 `-l` 以在项目本地安装(仅添加到 `.pi/settings.json`)。 无需手动设置:`playwright` npm 依赖会随包自动安装,Chromium 二进制文件(约 150 MB)会在首次启动浏览器时下载一次。如果想预先下载,可以在安装目录中运行 `npx playwright install chromium`。 ## 工作原理 ### 净化流水线(在每个结果上运行) 与 pi-safe-search 共享。每一段页面内容在到达 LLM 之前都会经过此流水线: 1. **Unicode 标准化** — NFKC 标准化加上同形异义字符映射,将相似字符折叠为 ASCII 2. **零宽字符移除** — 剔除用于隐藏指令的不可见字符 3. **控制字符剔除** — 移除空格以下的所有字符,除了 `\t`、`\n`、`\r` 4. **HTML 实体解码 → 重新剔除** — 解码 `<script>`,然后剔除生成的标签 5. **URL 解码** — 捕获百分号编码的 payload 6. **Base64 块脱敏** — 将可疑的 base64 块替换为 `[BASE64_ENCODED_DATA]` 7. **注入模式脱敏** — 覆盖指令、角色劫持、系统 prompt 提取、模式切换等 8. **随机分隔符包裹** — 内容使用随机 token 进行围栏处理,以便 LLM 将其中的所有内容视为数据,而不是指令 第二次净化过程通过 `tool_result` hook 在每个工具结果上运行,捕获任何漏网之鱼。 ### 网络层的 SSRF 保护 与普通的基于 fetch 的工具不同,渲染后的页面可以发出模型从未请求过的请求——重定向、iframe、XHR 调用、子资源。`context.route("**/*")` 拦截器会针对以下内容检查**每一个**请求: - 非 http(s) 协议(`file://`、`ftp://` 等) - 危险端口:21、22、25、53、3306、5432、6379 等 - RFC-1918、环回、链路本地和保留的 IP 范围(DNS 解析,60 秒缓存) `browser_open` 还会在导航开始前预先验证 URL,并给出描述性错误。 ### 浏览模型 该扩展维护一个延迟启动的浏览器/上下文以及一个“当前页面”。`browser_open` 导航并提取文本和链接;`browser_act` 在该页面上点击、输入、按键、滚动或等待;`browser_read` 通过字符偏移量分页浏览最后提取的内容,而无需重新抓取。打开新标签页的点击会自动切换到该标签页,对话框会自动关闭。 `browser_search` 有意在普通的 fetch 上使用 DuckDuckGo 的静态 HTML 端点 —— DDG 会屏蔽 headless Chromium —— 因此浏览器只花在需要它的地方:渲染页面并与之交互。 ## 工具 **`browser_search`** — 搜索 DuckDuckGo 并返回标题、URL 和摘要。 参数: - `query`(必填)— 搜索查询 - `max_results`(可选)— 结果数量,默认为 5,最大为 10 **`browser_open`** — 导航到 URL 并返回渲染后的文本以及链接列表。 参数: - `url`(必填)— 必须为 http 或 https **`browser_act`** — 与当前打开的页面进行交互:click、type、press、scroll 或 wait_for。 **`browser_read`** — 通过字符偏移量分页浏览最后快照中提取的文本,无需重新抓取。 ## 配置 持久配置存在于 `extensions/browser-search.json` 中(首次加载时自动创建并使用默认值)。你可以直接要求 agent 编辑它: ``` { "MAX_RESULTS": 5, "MAX_CHARS": 8000, "MAX_LINKS": 25, "NAV_TIMEOUT_MS": 30000, "HEADLESS": true, "BLOCK_MEDIA": true } ``` | 键 | 默认值 | 描述 | |-----|---------|-------------| | `MAX_RESULTS` | `5` | `browser_search` 返回的默认搜索结果数 (1–10) | | `MAX_CHARS` | `8000` | 每次 `browser_read` 分块返回的页面文本 | | `MAX_LINKS` | `25` | 每页列出的链接数 | | `NAV_TIMEOUT_MS` | `30000` | 导航超时(以毫秒为单位) | | `HEADLESS` | `true` | 设置为 `false` 以监视浏览器窗口 | | `BLOCK_MEDIA` | `true` | 跳过加载图像/媒体/字体 | 更改 `HEADLESS` 或 `BLOCK_MEDIA` 或 `NAV_TIMEOUT_MS` 会关闭当前浏览器,以便下一次调用时使用新选项重新启动。 对 JSON 的更改将在下一次会话中生效。要在会话中进行实时调整,请使用以下命令。 ## 命令 ``` /browser-search — show current status and config /browser-search set KEY=VAL — override config for the current session only /browser-search reset — close the browser ``` ## 兼容性 与 [pi-safe-search](https://github.com/sebaxzero/pi-safe-search) 共享其净化和 SSRF 模型 —— 如果你希望对大多数页面使用廉价的静态抓取,而将真实浏览器留给重度依赖 JS 的页面,请同时安装两者。 ## 依赖项 `playwright` (^1.53.0) —— 随包自动安装,无论是通过 `pi install npm:` 还是基于 git 的安装。Chromium 二进制文件将在首次启动浏览器时单独下载(参见上文的安装说明)。 ## 测试 ``` node --test test.mjs ``` 17 个测试,涵盖 IP 范围检查、URL 验证、DuckDuckGo 重定向 解包以及净化冒烟测试。纯逻辑存在于 `net.ts` 和 `sanitize.ts` 中(无 Playwright 导入),因此测试套件无需浏览器即可运行。 CI 会在每次推送和拉取请求时运行它。 ## 发布 更新 `package.json` 中的 `version`,提交,打上 `vX.Y.Z` 标签,并推送该标签 —— 发布工作流将运行测试并发布到 npm。 ## 许可证 MIT 使用 [Claude](https://claude.ai) 构建。
标签:AI工具集成, MITM代理, Playwright, SSRF防护, 提示词注入防御, 暗色界面, 特征检测, 自动化攻击, 自动化浏览器