# 审计 — 全局浮动浏览器

## 范围（文件清单）

| 文件 | 变更 |
|------|------|
| `server/utils/browser_ui_state.py` | URL 校验、visit 上限 |
| `server/api/browser.py` | `/api/browser/state` |
| `server/main.py` | 注册 browser 路由 |
| `frontend/src/composables/useGlobalBrowser.ts` | 全局状态 |
| `frontend/src/components/GlobalBrowserPanel.vue` | 浮动面板 |
| `frontend/src/composables/useFloatingPanel.ts` | 可配置最小尺寸，支持迷你条拖动 |
| `frontend/src/pages/BrowserPage.vue` | 打开全局窗并返回 |
| `frontend/src/App.vue` | 挂载 GlobalBrowserPanel |
| `frontend/src/pages/ServersPage.vue` | 站点按钮 |
| `frontend/src/composables/useEmbeddedBrowser.ts` | 删除（由 global 替代） |
| `tests/test_browser_ui_state.py` | 单测 |

## Step 3 规则扫描

| H | 规则 | 结论 |
|---|------|------|
| H1 | 无 SSRF | PASS — 无服务端 fetch |
| H2 | URL 白名单 | PASS — http/https only |
| H3 | 按管理员隔离 | PASS — admin_ui_preferences |
| H4 | iframe sandbox | PASS |

## Closure

| H | 判定 | 依据 |
|---|------|------|
| H1 | PASS | 纯 iframe，无 proxy |
| H2 | PASS | browser_ui_state._is_safe_url |
| H3 | PASS | AdminUiPreference per admin |
| H4 | PASS | GlobalBrowserPanel sandbox attr |

## DoD

- [x] pytest test_browser_ui_state.py
- [x] type-check
- [x] changelog

## 验证

浮动打开 → 最小化可拖动浮动条 → 左下角展开 → 不可关闭仅可重启 → 切换菜单 iframe 仍在。
