kadeemj/URL-Safety-Checker

GitHub: kadeemj/URL-Safety-Checker

一款混合型 URL 安全分析工具,结合 14 项本地启发式检查与 Google Safe Browsing 信誉查询,生成可解释的 0–100 风险评分并附带通俗的证据说明。

Stars: 0 | Forks: 0

# URL 安全检查器 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/kadeemj/URL-Safety-Checker/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) 粘贴链接,获取判定结果——以及背后的原因。 一款混合型 URL 分析工具:**14 项本地计算的安全启发式检查**,外加 **Google Safe Browsing** 信誉查询,综合生成可解释的 0–100 风险评分。最终评分中的每一分都可以追溯到一项具名的检查以及 通俗易懂的证据,因此报告会告诉你链接*为什么*有风险,而不是 直接给出一个不透明的判定。 **在线演示:** https://kadeemj.github.io/URL-Safety-Checker/ ## 架构 ``` ┌─────────────────────┐ POST /api/v1/check ┌──────────────────────────┐ │ GitHub Pages │ ────────────────────► │ FastAPI on Render │ │ (static frontend, │ │ │ │ vanilla JS) │ ◄──────────────────── │ 1. validate + SSRF guard │ └─────────────────────┘ JSON report card │ 2. 12 local heuristics │ │ 3. concurrently: │ │ · Google Safe Browsing│ │ · RDAP domain age │ │ · redirect chain walk │ │ 4. score + verdict │ └──────────────────────────┘ ``` - **Frontend** (`docs/`):纯 HTML/CSS/JS,无框架,无构建步骤。 由 GitHub Pages 托管。所有 API 返回的字符串均使用 `textContent` 渲染——被分析的 URL 属于攻击者可控的输入,绝不能 被直接内插到 HTML 中。 - **Backend** (`backend/`):FastAPI + httpx。Safe Browsing API key 仅存放在 服务器环境中。CORS 限制为 Pages 源,并且 基于 IP 的滑动窗口速率限制保护着公共 endpoint。 ## 检查项 | 检查项 | 信号 | 最高扣分 | |---|---|---| | 欺骗性 URL 用户名 | `https://paypal.com@evil.example` 实际访问的是 evil.example | 25 | | 仿冒域名 (typosquatting) | 与 55 个顶级品牌的 Levenshtein 距离;子域名中包含品牌名 | 25 | | 仿冒字符 (homoglyphs) | Punycode/IDN 骨架匹配品牌名 (`pаypаl` ≠ `paypal`) | 25 | | 原始 IP 地址主机 | 无域名,无问责 | 20 | | 域名年龄 (RDAP) | 注册 <30 天 (+20) 或 <180 天 (+10) | 20 | | 重定向链 | 长度、短链接跳转、重定向至私有地址空间 | 15 | | 异常长 / 随机 URL | 长度分级 + 路径/查询参数的香农熵 | 12 | | URL 缩短服务 | 目的地被隐藏——这是一种不透明性惩罚,而非指控 | 12 | | 钓鱼诱饵关键词 | 在外部域名上出现 `login`/`verify`/`secure` + 品牌关键词 | 12 | | 未加密 (http) | 凭证页面应使用 HTTPS | 10 | | 高滥用率 TLD | `.tk`, `.zip`, `.top`, …… 权重较低:单独作为弱信号 | 10 | | 非标准端口 | 临时搭建的基础设施 | 8 | | 过多的子域名 | `login.secure.account.verify.example.com` | 8 | | 机器生成的域名 | 连字符/数字密集的可注册域名 | 8 | | **Google Safe Browsing** | 确认的恶意记录将**覆盖一切**(见下文) | — | **评分标准:** `score = min(100, Σ triggered penalties)` → 0–24 **安全** · 25–59 **可疑** · 60–100 **危险**。 有两个不对称设计是有意为之的: - Safe Browsing **命中** 会强制将判定结果设为危险,并将分数下限设为 95——Google 已确认存在主动滥用;启发式检查无法降低其分数。 - Safe Browsing **未命中不会扣分**。没有证据并不代表 证据不存在:全新的钓鱼页面可能尚未被收录。 无法运行的检查项(RDAP 超时、缺少 API key)将报告为 `unavailable`,扣除零分,并将响应的 `confidence` 字段降级为 `partial`——该工具绝不会因为 我们自身的宕机而惩罚某个 URL,也绝不会在未实际执行查询时 假装已进行过查询。 ## 威胁模型说明 这里有趣的安全问题在于,该服务会**获取 攻击者提供的 URL**(重定向遍历),这是一个教科书式的 SSRF 攻击向量。 `backend/app/validation.py` 实现了以下防护: - scheme 白名单 (http/https)、长度限制、被阻断的主机名后缀 (`.local`, `.internal`, `.onion`, localhost) - 字面量 IP 筛查,包含整数编码形式 (`http://2130706433/` 即 `127.0.0.1`) - DNS 解析检查:对主机名进行解析,如果发现**任何** 非全局地址则拒绝(阻断通过 DNS-rebinding 指向 `169.254.169.254` 等地址的行为) - 该防护在**每次重定向跳转时都会重新运行**,并且在任何 外部请求之前都会剥离 URL 中的凭证 其他安全加固措施:源限制 CORS、基于 IP 的速率限制 (在 Render 的代理后感知 `X-Forwarded-For`)、非 root Docker 镜像、 不持久化存储提交的 URL。 ## 本地运行 ``` # backend — Python 3.12+ cd backend python3 -m venv .venv && source .venv/bin/activate pip install -r requirements-dev.txt cp .env.example .env # optionally add your Safe Browsing key uvicorn app.main:app --reload # http://localhost:8000 # frontend — 任意静态服务器 cd ../docs python3 -m http.server 3000 # http://localhost:3000 ``` 无需任何 API key 即可运行——Safe Browsing 检查只会报告 `unavailable`,而 14 项启发式检查仍会正常运行。 ``` # tests + lint cd backend pytest # 125 tests, all external calls mocked (respx) ruff check . ``` ## 部署 1. **Backend → Render:** "New +" → Blueprint → 指向此仓库 (`render.yaml` 会配置一切)。在仪表板中设置 `GOOGLE_SAFE_BROWSING_API_KEY`。 2. **Frontend → GitHub Pages:** 仓库 Settings → Pages → 从分支 `main`、文件夹 `/docs` 进行部署。 3. 将 `docs/js/config.js` 指向你的 Render URL。 ## 局限性(已知且接受) - 速率限制器是基于内存的——在 Render 的单实例免费 层级上是准确的,但在多实例部署中计数会偏低。 - 品牌列表包含约 55 个域名;未列入榜单的品牌的 typosquat 不会被匹配。 - Render 的免费层级在空闲时会休眠;每天首次扫描大约需要 30–60 秒(UI 在等待期间会对此进行说明)。 - “安全”判定意味着*未发现风险信号*,而不是*被证明安全*。它是一个咨询 工具,而非神谕。 ## License MIT
标签:请求拦截, 调试辅助, 运行时操纵, 逆向工具