qruiqai/leakish

GitHub: qruiqai/leakish

一款浏览器端隐私泄露检测器,通过八大模块检测 WebRTC、指纹、DNS 等泄露风险并提供评分与历史分析。

Stars: 3 | Forks: 1

Leakish

浏览器隐私泄露检测器 —— 包含八大检测模块、风险评分以及 按账户划分的历史记录,全部在你的浏览器中运行。

Built with Verdent Next.js 14 React 18 TypeScript 5 Prisma

## 这是什么 打开一个 URL,点击 **Run all**,几秒钟内 Leakish 就会告诉你 你的浏览器正在泄露关于你和你网络的哪些信息 —— 包括 WebRTC、 指纹 API、DNS 以及服务端探测。八个独立模块各自生成类型化的结果 + 风险信号、一个综合评分(0–100)以及对应的风险等级 (`safe` / `warning` / `critical`)。 已登录的用户可以将扫描结果保存到 MySQL,浏览历史记录,并打开分析 仪表板,其中展示了分布图、指纹哈希重复情况、IP / ASN 时间轴、异常扫描以及两两对比。其他所有功能(检测器本身)无需 账号即可使用 —— 任何人都可以进入 `/app` 并运行扫描。 ## 检测模块 | ID | 模块 | 检测内容 | | --------------------- | -------------------- | ------------------------------------------------------------------------------------------- | | `network-probe` | 网络出站探测 | 服务端观测到的公网 IP、ASN、国家/地区/城市、VPN/代理/Tor/托管标记、TLS/HTTP | | `webrtc` | WebRTC | 通过 STUN 获取的公网 IPv4 + IPv6、RFC1918 泄露、mDNS 混淆的 `.local` 候选地址 | | `browser-fingerprint` | 浏览器指纹 | UA、屏幕、时区、插件、CPU 核心数、设备内存、语言列表、DNT、cookie | | `canvas-fingerprint` | Canvas / WebGL | 2D + WebGL 渲染器/厂商字符串、文本渲染特性、支持的图像格式 | | `audio-fingerprint` | Audio | `AudioContext` 采样率、声道、延迟、振荡器输出哈希 | | `font-detection` | 字体 | 通过 Canvas 宽度差检测对 40 多种命名字体进行探测 | | `dns` | DNS | DoH 可达性、DNSSEC 信号、解析器地理位置、DNS 泄露启发式检测 | | `cdp-detection` | 自动化 / 无头模式 | `navigator.webdriver`、CDP 计时、Chromium 独有 API 接口、端口探测 —— 置信度为 0–1 | 每个模块都通过统一的类型化 `DetectionModule` 接口注册,并独立 运行 —— 某个模块抛出异常不会影响其他模块。每个模块的启用状态会通过带版本号的 key 持久化存储在 `localStorage` 中,在页面刷新后依然保留,并且 **Run all** 按钮只会遍历已启用的模块集合。 ## 功能 - **浏览器内检测** —— 每个模块都在用户的浏览器标签页中运行。只有在以下情况服务器才会 参与:(a) 用户已登录并保存扫描结果,(b) network-probe 模块请求 `/api/detect/network` 以读取其自身服务端观测到的 IP,或 (c) DNS 模块与 `https://dns.google/resolve` 通信。 - **双语界面** —— 完整的中英文对等支持。语言环境存储在 `leakish.locale` cookie 中,它控制着 ``、页面元数据、每一个界面、 每一个 API 错误响应以及 magic-link 登录邮件。 - **身份验证** —— 使用 NextAuth 结合 Google OAuth + magic-link 邮件; 在 MySQL 上使用 Prisma adapter。在开发环境中 Email 是可选的 —— 如果未配置 Mailgun,链接将直接打印到服务器 日志中。 - **编程访问** —— 用户可以在 _Integrations_ 页面生成 `det_…` API key(以 SHA-256 存储,明文仅显示一次)。每个 `/api/detect/*` endpoint 都接受 session cookie 或 Bearer key,因此 可以从 CLI / CI 任务中保存相同的扫描。 - **分析仪表板** 位于 `/scans/analytics` —— 涵盖 时区 / 平台 / 语言 / 屏幕 / WebGL / ASN / 国家 / 字体数量的分布图表, 按类型划分风险等级的指纹哈希重复情况,IP / ASN 时间轴, 多轴异常检测器,以及具有 0–100 相似度评分的两两对比。 - **具有单信号可溯源性的风险模型** —— `lib/risk/assess.ts` 会生成 具有稳定 ID(例如 `webrtc.public-ip-leak`)的类型化 `RiskSignal`、各模块的 摘要,以及一个综合评分。通过 `Messages` 注入实现本地化。 - **幂等保存 + 按用户修剪** —— `POST /api/detect/scans` 接受 `Idempotency-Key` header,将每个用户的上限设为 200 次扫描,并将保存频率限流至 每小时 10 次。 - **生产级 Docker 镜像** —— 在 `node:22-alpine` 上进行多阶段构建, Next.js standalone 输出,通过 `.github/workflows/` 下的 workflow 部署到 Kubernetes。 ## 快速开始 前置条件:Node 22+(本地开发 20+ 版本即可),Yarn 1.x,一个运行中的 MySQL 实例,以及(可选的)一个 Google OAuth client。 ``` yarn install cp env.example .env.local # fill in DATABASE_URL, NEXTAUTH_SECRET, IP_HASH_SALT at minimum yarn prisma:generate yarn db:push # provision tables on a fresh DB yarn dev # http://localhost:3000 ``` 实现基础登录功能所需的最低环境变量: - `DATABASE_URL` —— 例如 `mysql://root:password@127.0.0.1:3306/detect` - `NEXTAUTH_SECRET` —— `openssl rand -base64 32` - `NEXTAUTH_URL` —— 开发环境中为 `http://localhost:3000` - `IP_HASH_SALT` —— `openssl rand -base64 32` 可选配置: - 用于 Google 登录的 `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` - 用于真实 magic-link 发送的 `MAILGUN_API_KEY` / `MAILGUN_DOMAIN` / `EMAIL_FROM` (如果没有这些,链接将被打印到开发服务器控制台) - 用于通过 ASN / VPN / 代理数据丰富网络探测的 `IPINFO_TOKEN` 完整带有注释的列表请参见 [`env.example`](env.example)。 ## 路由 | 路径 | 用途 | | ----------------- | --------------------------------------------------------- | | `/` | 营销主页(极光主视觉、功能卡片、FAQ、CTA) | | `/app` | 检测器 —— 模块列表 + 结果面板 + 概览 | | `/login` | 独立登录页面(Google / Email / API key) | | `/scans` | 已登录用户的已保存扫描历史 | | `/scans/[id]` | 单个已保存扫描详情 | | `/scans/analytics`| 分布 / 重复 / 时间轴 / 异常 / 对比 | | `/integrations` | 管理 `det_…` API key(创建 / 吊销 / 操作指南) | ## 项目结构 ``` app/ ├── (marketing)/ # / — Landing (server-resolved auth state + client UI) ├── app/ # /app — the detector page ├── login/ # /login ├── scans/ # /scans, /scans/[id], /scans/analytics ├── integrations/ # /integrations — API key management ├── api/ │ ├── auth/ # NextAuth route + apiKey-login + tests │ ├── detect/ │ │ ├── analytics/ # aggregate + pairwise-diff │ │ ├── network/ # server-side egress probe │ │ ├── scans/ # save / list / get / delete │ │ └── uniqueness/ # how many users share this fingerprint hash │ ├── integration/keys # create / revoke / list API keys │ └── health/ # liveness probe for k8s ├── opengraph-image.tsx # dynamic OG (per-locale) ├── apple-icon.tsx # dynamic apple-touch icon ├── icon.svg # shield gradient └── layout.tsx # metadata + theme-init script + LocaleProvider components/ ├── modular-detector.tsx # top-level shell (header + module list + result/overview) ├── detector/ # module-list, result-panel, category filter, state hook ├── result-details/ # one detail view per module (typed switch) ├── overview/ # overview panel + diagnostics export ├── auth/ # AuthGateProvider, login dialog, login form ├── providers/ # SessionProvider wrapper └── ui/ # shadcn-style primitives + theme/locale toggles lib/ ├── detection-modules/ # 8 module impls + ModuleManager + IP utils + tests ├── risk/ # assess.ts — RiskSignal/score aggregation ├── i18n/ # en.ts / zh.ts + Messages type + locale client/server ├── api/ # withDetectAuth wrapper, scan-payload Zod schema ├── client/ # browser-side scan-api (extractFingerprintInputs, saveScan, lookupUniqueness) ├── server/ # network-probe, IP-hash salt, fingerprint hashing, rate-limit, send-email, analytics ├── persistence/ # SSR-safe localStorage wrappers ├── env.ts # runtime env validation ├── logger.ts # dev-only diagnostic logger └── prisma.ts # singleton client targeted at .prisma/detect-client prisma/schema.prisma # User / Account / Session / DetectScan / ApiKey / DetectFingerprintHash ``` ## 扫描的完整工作流程 1. 用户在 `/app` 中点击 **Run all**。检测器通过 `ModuleManager.runAllEnabledModules` 遍历已启用的模块 —— 每个模块的失败都会被捕获并隔离,以便其他结果仍能正常显示。 2. 每个模块都会返回一个类型化的 `DetectionResult`(带有 `success | failure` 标记和特定模块的 `data`)。结果面板通过类型安全的 `switch` 渲染每个模块对应的详情组件。 3. `lib/risk/assess.ts` 遍历每个结果,发出带有稳定 ID 的 `RiskSignal`, 并生成 `OverallAssessment`(评分 + 等级 + 计数)。 4. 在 **Save this scan** 时,客户端会提取结构化的 payload + 指纹 哈希(canvas2d / webgl / audio / fontset / UA),并将其 `POST` 到 `/api/detect/scans`。服务器通过 Zod 进行验证,运行自己的网络 探测以记录服务端观测到的 IP / ASN / VPN 标记,并写入一条 `DetectScan` 记录以及多条 `DetectFingerprintHash` 记录。 5. 随后,扫描结果可在 `/scans/[id]` 处查看,它会被纳入分析 聚合,并计入唯一性查询。 ## 技术栈 | 层级 | 组件 | | -------------- | --------------------------------------------------------------------------- | | 框架 | Next.js 14 (App Router, 到处使用 `force-dynamic`), React 18 | | 语言 | TypeScript 5, 严格模式 | | UI | Tailwind CSS 3, 基于 Radix 的 shadcn/ui 原语, Lucide icons, Framer Motion | | 认证 | NextAuth 4 (Google OAuth + magic-link email) + Prisma adapter | | 数据 | Prisma 6 → MySQL (自定义 client 输出位于 `.prisma/detect-client`) | | 校验 | Zod | | 测试 | Jest 29 + ts-jest + jsdom | | 构建 / 部署 | 多阶段 Dockerfile, Next.js standalone, Kubernetes manifests | ## 测试 单元测试位于其测试目标旁边的 `__tests__/` 目录中: ``` yarn test # full suite yarn test path/to/file # single file yarn test -t "name pattern" # by test-name regex ``` 主要内容: - `lib/detection-modules/__tests__/` —— IP 分类 + mDNS 提取, 模块管理器注册与故障隔离,用于 WebRTC 模块的模拟 `RTCPeerConnection`, 用于浏览器指纹模块的 jsdom-shape 测试, CDP/自动化信号生成。 - `lib/server/__tests__/analytics.test.ts` —— 分布分桶、重复 分组、异常评分、两两相似度计算。 - `app/api/detect/scans/__tests__` —— POST 保存(校验、速率限制、 幂等性、修剪)+ GET 列表 + DELETE 单条记录。 - `app/api/integration/keys/__tests__` —— 结合模式限制的创建 / 吊销 / 列表 (API-key 会话无法生成其他 API key)。 - `app/api/auth/__tests__` —— apiKey-login 路由(CSRF、格式检查、已吊销 / 过期处理、last-used 更新)。 Lint + 类型检查: ``` yarn lint npx tsc --noEmit ``` ## 部署 包含的 `Dockerfile` 会基于 `node:22-alpine` 生成 Next.js standalone 镜像。生产环境变量通过 Kubernetes Secret 注入 —— 占位符 值在构建时已写入,因此运行时不需要 `SKIP_ENV_VALIDATION`。一个 `prisma db push` Job 会在发布前运行 schema 更新。完整的镜像构建 → 迁移 → 发布 流水线请参见 `.github/workflows/deploy-tke.yml`。 ## 计费与订阅 这个开源版本没有付费墙。保存功能仅受 `lib/server/rate-limit.ts` 中的进程内 用户级速率限制器控制(每小时 10 次保存),并且历史记录 保留时间不受限制。 ## 鸣谢 - **[Verdent](https://www.verdent.ai/?id=701236)** —— 用于端到端构建此项目的 智能编码助手。 - **[NextAuth](https://next-auth.js.org/)** —— 身份验证基础设施。 - **[Prisma](https://www.prisma.io/)** —— schema、迁移及生成的 client。 - **[shadcn/ui](https://ui.shadcn.com/)** + **[Radix UI](https://www.radix-ui.com/)** —— 此 UI 所基于的无障碍原语。 - **[Tailwind CSS](https://tailwindcss.com/)** —— 样式系统。 - **[ipinfo.io](https://ipinfo.io/)** —— 网络探测所使用的免费 ASN / VPN 数据。 - **[Mailgun](https://www.mailgun.com/)** —— 生产环境中的 magic-link 邮件发送服务。 ## License 参见 [LICENSE](LICENSE)。
标签:Prisma, React, Syscalls, WebRTC, 子域名突变, 浏览器指纹, 自动化攻击, 请求拦截, 隐私检测, 风险评分