urlert/urlert-guard
GitHub: urlert/urlert-guard
开源可审计的浏览器扩展,提供实时域名威胁情报与恶意网站防护。
Stars: 1 | Forks: 0
# 🛡️ URLert Guard (源码可见)
针对风险和恶意域名的实时防护。URLert Guard 使用专有的威胁情报来保护您的安全。
本代码库包含 URLert Guard 扩展的客户端源代码。
### 为什么要公开?
我们信奉“透明胜于晦涩”。我们公开代码,以便安全研究人员和用户能够验证我们的隐私声明并审计数据处理方式。
**许可证:** 源码可见,仅供检查。请参阅 [LICENSE](LICENSE)。
## 从源码构建
前置条件:[Node.js](https://nodejs.org/) (v18+) 和 npm。
```
npm install # install dependencies
npx wxt # dev mode with hot reload (Chromium)
npx wxt build # production build → .output/chrome-mv3/
```
Firefox:
```
npx wxt -b firefox # dev mode
npx wxt build -b firefox # production build
```
## 安全审计指南
本代码库以源码可见的形式发布,以便安全研究人员、审查人员和用户能够确切检查该扩展的功能。以下是针对安全性相关代码的引导式说明。
### 权限
在 [`wxt.config.ts`](wxt.config.ts) 中声明:
| 权限 | 用途 |
|---|---|
| `tabs` | 读取活动标签页的 URL 以对域名进行分类并发送扫描请求。 |
| `storage` | 持久保存 auth token、设置、扫描历史记录和域名分类缓存。 |
| `activeTab` | 当用户明确请求扫描时,捕获可见标签页的屏幕截图。 |
| `host_permissions: *://api.urlert.com/*` | 所有网络请求均独占发往 URLert API。不联系任何其他外部主机。 |
### 网络请求
所有 API 调用均位于 [`src/lib/api.ts`](src/lib/api.ts) 中。每个请求都发往 `https://api.urlert.com/extensions/*`(或在开发环境中发往 `localhost`)。使用的端点:
| 端点 | 需要认证 | 用途 |
|---|---|---|
| `GET /extensions/domain-classification/{domain}` | 否 | 在导航时对域名进行分类 |
| `POST /extensions/scan` | 是 | 提交按需扫描(截图 + HTML) |
| `GET /extensions/scan/{job_id}` | 是 | 轮询扫描作业状态 |
| `POST /extensions/report` | 否 | 提交 URL 威胁报告 |
| `GET /extensions/subscription` | 是 | 获取用户的订阅层级 |
| `GET /extensions/auth/me` | 是 | 验证当前的 auth token |
**域名隐私:** 域名在被发送到 API 之前会被规范化为其注册域名 (eTLD+1) —— 例如,`mail.example.com` 会作为 `example.com` 发送。子域名永远不会泄露给服务器。请参阅 [`src/lib/api.ts`](src/lib/api.ts) 中的 `getDomain()` 调用。
**不会向任何第三方服务发送数据。** [`src/lib/types/api.generated.ts`](src/lib/types/api.generated.ts) 中生成的 API 类型仅筛选为这些端点 —— 不包含任何其他后端 schema。
### 认证
认证流程概览:
1. 用户点击“登录” → 在新标签页中打开 `urlert.com/extension/auth`。
2. 登录后,该页面发送一个带有 opaque token 的 `window.postMessage`。
3. [`auth-listener`](src/entrypoints/auth-listener.content.ts) content script(仅在 `urlert.com` 上运行)根据受信任的源允许列表验证消息来源,然后将 token 转发给 background script。
4. [background auth handler](src/entrypoints/background/handlers/auth.ts) 在存储 token 之前,根据相同的受信任源验证发送者标签页的 URL。
5. Token 存储在 `browser.storage.local` 中,并在经过认证的 API 调用中作为 `Bearer` header 附加。
扩展程序永远看不到 `user_id` 或 `organization_id` —— 后端从 token 解析身份。
### Content Scripts
| 脚本 | 运行位置 | 功能 |
|---|---|---|
| [`auth-listener.content.ts`](src/entrypoints/auth-listener.content.ts) | 仅 `urlert.com` | 监听 auth `postMessage`;验证来源;将 token 转发给 background。 |
| [`content/index.ts`](src/entrypoints/content/index.ts) | `` | 渲染一个 Shadow DOM 覆盖层图标以显示域名安全性。响应来自 background script 的 `URLERT_GET_PAGE_HTML`(仅用于用户发起的扫描)。 |
`` content script **不会**自动将任何页面数据发送到任何地方。`URLERT_GET_PAGE_HTML` handler 仅响应来自扩展自身 background script 的消息(网页 JavaScript 无法访问 `browser.runtime.onMessage`)。页面 HTML 仅在用户明确请求扫描时才会被捕获。
### 按需扫描
当用户点击“发送以进行分析”时:
1. 通过 `browser.tabs.captureVisibleTab` 捕获屏幕截图(需要 `activeTab`)。
2. Background script 向 content script 请求页面 HTML。
3. 两者连同页面 URL 一起发送到 `POST /extensions/scan`。
用户会看到一个同意屏幕 ([`ScanConfirm.svelte`](src/entrypoints/popup/views/scan/ScanConfirm.svelte)),其中列出了将要发送的确切内容,并带有警告以避免扫描包含个人或敏感信息的页面。
### 数据存储
所有数据存储在 `browser.storage.local` 或 `browser.storage.sync` 中:
| 键 | 存储位置 | 内容 |
|---|---|---|
| `urlertAuth` | local | Auth token、电子邮件、过期时间(明文 —— 见下文威胁模型) |
| `installId` | local | 用于匿名指纹识别的随机 UUID |
| `domainCache` | local | 带有 TTL 的缓存域名分类 |
| `urlertActiveScan` | local | 当前进行中的扫描状态 |
| `urlertScanHistory` | local | 最近 30 条已完成的扫描结果 |
| 设置键 | sync | 覆盖层偏好设置(位置、自动关闭等) |
**auth 存储的威胁模型:** `browser.storage.local` 未加密。这是 Chrome 扩展存储模型的一个公认限制 —— 嵌入在扩展中的任何加密密钥都是可提取的。Token 过期(由服务器端设置)是主要的缓解措施。有权访问 Chrome 配置文件目录的恶意进程无论是否进行客户端加密都可以读取此数据。
### HTML 净化
管理员备注 ([`UrlertNote.svelte`](src/lib/components/domain/UrlertNote.svelte)) 通过 `marked` 渲染为 Markdown,并在通过 `{@html}` 注入之前使用 `DOMPurify` 进行净化。虽然管理员备注内容完全由工作人员编写,但考虑到扩展弹出窗口有权访问特权 `browser.*` API,因此应用净化作为纵深防御措施。
### 本扩展不做的事情
- **不收集浏览历史记录。** 域名分类在导航时发生,但结果在本地缓存;不向服务器发送历史记录。
- **不泄露子域名。** 域名在任何 API 调用之前都被规范化为 eTLD+1 —— 服务器永远看不到完整的主机名。
- **不自动捕获页面内容。** HTML 和截图仅在明确的用户发起扫描期间发送。
- **无跨扩展通信。** 未声明 `externally_connectable`。
- **无远程代码执行。** 无 `unsafe-eval`、`unsafe-inline` 或动态脚本加载。
- **无第三方分析或跟踪。**
### 报告漏洞
请参阅 [SECURITY.md](SECURITY.md)。
标签:API 集成, Chrome 扩展, CMS安全, Firefox 插件, GNU通用公共许可证, JavaScript, MITM代理, Node.js, URL 扫描, WXT, 域名分类, 威胁情报, 实时防护, 客户端安全, 开发者工具, 浏览器扩展, 网络安全, 网络安全, 网页安全, 钓鱼防护, 隐私保护, 隐私保护