aqiah/PhishGuard
GitHub: aqiah/PhishGuard
PhishGuard 是一个基于 FastAPI 和机器学习的钓鱼链接检测工具,通过 URL 特征分析、域名信誉查询、DOM 检查和二维码扫描来评估网页的钓鱼风险。
Stars: 0 | Forks: 0
# PhishGuard — AI 钓鱼页面检测器
一个基于 FastAPI 的 Web 应用,它通过将基于词汇 URL 特征的 Random Forest 分类器与实时的域名信誉信号(TLS 证书有效性和 WHOIS 注册时长)相结合,来评估 URL 的钓鱼风险。
## v1.2 的新功能
在核心扫描器的基础上增加了四个高价值的检测功能:
- **可解释 AI (`app/xai_engine.py`)** — 将原始的模型/DOM 信号转换为
排序后的人类可读发现列表,每个发现都标记为
`CRITICAL` / `HIGH` / `MEDIUM` / `INFO`(“为什么它很危险”的详细分析)。
包括品牌冒充 / 域名抢注检测。
- **QR "QRishing" 扫描器 (`app/qr_scanner.py`)** — 解码上传的 QR 图像
(通过 Pillow + OpenCV 支持 PNG/JPG/WEBP),并对嵌入的 URL 执行完整的处理流水线。
- **DOM 和表单检查器 (`app/dom_inspection.py`)** — 获取页面(在
相同的 SSRF 防护措施之后),并使用 BeautifulSoup 标记 HTTP 上的密码输入框、向第三方
域名提交的表单、自动重定向和右键点击拦截。
- **Chrome 扩展支持** — 带有 CORS 的 `/api/v1/*` 端点,允许
`chrome-extension://` / `moz-extension://` 源(绝不共享凭据)。
### v1.2 API 端点
| 方法 | 路径 | 请求体 | 目的 |
| --- | --- | --- | --- |
| POST | `/api/v1/analyze` | `{"url": "...", "inspect_dom": true}` | 全面扫描:风险评分、信号、DOM 报告、XAI 发现 |
| POST | `/api/v1/scan-qr` | multipart `file=` | 解码 QR 然后执行全面分析 |
| POST | `/analyze` | `{"url": "..."}` | 传统的词汇 + 信誉扫描(出于兼容性保留) |
增强后的响应增加了 `findings` (XAI)、`dom`(检查报告)、
`threat_level`(最高发现的严重程度)、`source` (`url`/`qr`) 和 `decoded_url`。
## 建议的测试链接
将这些粘贴到 UI 中(或通过 `POST /analyze`)来测试检测器:
| 预期 | URL |
| --- | --- |
| 低风险 | `https://github.com` |
| 低风险 | `https://www.wikipedia.org` |
| 低风险 | `google.com`(自动添加协议头) |
| 高风险 | `http://10.0.0.1@login-update-account.com/verify` |
| 高风险 | `http://secure-login.bank-update-check.info/signin` |
| 高风险 | `http://paypal.com@verify-account-update.xyz/login` |
| 被阻止 (SSRF) | `http://127.0.0.1/admin` |
| 被阻止 (SSRF) | `https://169.254.169.254/latest/meta-data/` |
| 被阻止 (端口) | `https://example.com:8443/` |
## 这是 DevSecOps 吗?
**不是一个完整的 DevSecOps 平台。** 这是一个内置了安全强化(安全编码 + 测试)的应用程序。
一个完整的 DevSecOps 设置还将包括 CI 流水线、
SAST/DAST、依赖项扫描(例如 Dependabot/`pip-audit`)、容器镜像扫描、
签名发布、密钥管理和生产环境监控。这些在
这里尚未接入。*已包含*的内容:
| 控制 | 状态 |
| --- | --- |
| 输入验证 / URL 净化 | 是 |
| SSRF 防护(私有/元数据 IP,DNS 检查,端口锁定) | 是 |
| 从扫描的 URL 中剥离凭据 | 是 |
| `/analyze` 上的速率限制 | 是 |
| 安全响应头(CSP, XFO, nosniff, Referrer-Policy) | 是 |
| 严格的 CORS(默认拒绝) | 是 |
| 防 XSS 的 DOM 渲染(`textContent`,无 `innerHTML`) | 是 |
| 自动化 pytest 套件(包含 SSRF 用例) | 是 |
| CI/CD, SAST, 依赖项 CVE 检查门禁, WAF, 身份验证 | 否 |
**没有任何应用程序是“零漏洞”的。** 强化可以降低风险;但并不能消除
风险。剩余的潜在风险包括高级 DNS 重绑定攻击、随着时间推移出现的依赖项 CVE,以及合成 ML 模型的假阳性/假阴性。
## 安全强化 (v1.1)
只有在验证了目标主机名并确认每个 DNS
回答都是**公共** IP 之后,才会执行出站 SSL/WHOIS 查询。私有、环回、链路本地、多播、
文档 (TEST-NET) 和云元数据目标都会被拒绝并返回 HTTP `400`。
非默认端口会被拒绝。`/analyze` 受速率限制(默认每个客户端 IP 每 60 秒 30 次请求;可通过 `PHISHGUARD_RATE_LIMIT` / `PHISHGUARD_RATE_WINDOW` 进行配置)。
## 工作原理
扫描分三个阶段进行:
1. **规范化** (`app/scanner.py`) — 提交的字符串会被修剪、
验证,并添加协议限定(`example.com` 会变成 `https://example.com`)。
非 Web 协议、无主机输入、私有目标和非默认端口会被
拒绝并返回 `400`。嵌入的凭据将从返回的 URL 中剥离。
2. **特征提取** — 从
剥离前的格式中计算六个词汇/启发式特征,以便经典的 `user@host` 钓鱼技巧仍然会被扣分:URL 长度、
嵌入的 IP 地址、`@` 混淆、点计数、HTTPS 使用情况和凭据诱饵
关键字。
3. **评分** (`app/model.py`) — 特征向量被输入到训练好的
`RandomForestClassifier` 中。然后,生成的概率会根据实时的
信誉信号进行调整:缺少 TLS 证书和新近注册的域名
会推高分数,而长期存在的 HTTPS 域名则会拉低分数。
最终分数会被限制在 0–100 之间,并划分为 `LOW` / `MEDIUM` / `HIGH`。
SSL 握手和 WHOIS 查询在并行的工作线程中运行,每个线程都有自己的超时设置,因此缓慢或无响应的 WHOIS 服务器不会阻塞请求。任何
查询失败都会降级为中性默认值,而不是导致扫描报错。
## 项目结构
```
PhishGuard/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app, endpoints, orchestration
│ ├── model.py # Random Forest training + risk scoring
│ ├── scanner.py # URL normalization, features, SSL/WHOIS + SSRF guards
│ ├── xai_engine.py # Explainable-AI findings (Why It's Dangerous)
│ ├── qr_scanner.py # QR image decoding (Pillow + OpenCV)
│ ├── dom_inspector.py # SSRF-safe fetch + BeautifulSoup form/DOM analysis
│ └── security.py # Headers, rate limit, CORS (extension-aware)
├── static/
│ ├── app.js # Fetch API client, tabs, XSS-safe rendering
│ └── style.css # Supplemental styling on top of Tailwind
├── templates/
│ └── index.html # Tailwind UI: URL + QR tabs, XAI + DOM grid
├── tests/
│ ├── conftest.py # Offline mode + QR/image fixtures
│ ├── test_api.py # Integration tests (all endpoints, CORS, SSRF)
│ ├── test_scanner.py # Extraction, normalization, scoring, SSRF
│ ├── test_xai.py # Explainable-AI rule coverage
│ ├── test_dom.py # DOM/form inspection
│ └── test_qr.py # QR decode round-trips
├── pytest.ini
├── requirements.txt
└── README.md
```
## 设置
```
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txt
```
## 运行服务器
```
uvicorn app.main:app --reload
```
然后打开 。交互式 API 文档位于 `/docs`。
## 运行测试
```
pytest
```
测试完全在离线状态下运行 — `PHISHGUARD_OFFLINE` 环境变量由
`tests/conftest.py` 设置,它会短路 SSL 和 WHOIS 查找(以及速率
限制器),从而使测试套件具有确定性和快速性。您可以手动设置相同的变量,以便在没有网络访问的情况下运行应用程序本身。
## API
### `POST /analyze`
请求:
```
{ "url": "http://10.0.0.1@login-update-account.com/verify" }
```
响应 `200 OK`:
```
{
"url": "http://10.0.0.1@login-update-account.com/verify",
"domain": "login-update-account.com",
"is_phishing": true,
"risk_score": 78.7,
"risk_level": "HIGH",
"model_confidence": 66.7,
"signals": {
"has_ssl": false,
"domain_age_days": 0,
"uses_ip": true,
"has_at_symbol": true,
"suspicious_keywords": true,
"subdomain_count": 4,
"url_length": 47,
"is_https": false,
"reputation_lookup_ok": false
},
"reasons": [
"Raw IP address used in place of a domain name.",
"'@' symbol can hide the true destination host.",
"URL contains credential-harvesting keywords.",
"Connection is not encrypted (plain HTTP).",
"Unusually deep subdomain nesting.",
"No valid TLS certificate served on port 443."
]
}
```
错误响应:
| 状态 | 原因 |
| --- | --- |
| `422` | 缺少/为空的 `url` 字段,类型错误,或 URL 超过 2048 个字符 |
| `400` | 语法无效的 URL,不支持的协议,或无可解析的主机 |
| `502` | 扫描流水线内部发生意外故障 |
### `GET /health`
存活探针,返回 `{"status": "ok", "model": "RandomForestClassifier"}`。
## 配置
| 变量 | 默认值 | 效果 |
| --- | --- | --- |
| `PHISHGUARD_OFFLINE` | 未设置 | 设置为 `1` 可跳过所有 SSL/WHOIS 网络查找 |
超时设置位于 `app/scanner.py` (`SSL_TIMEOUT_SECONDS`, `WHOIS_TIMEOUT_SECONDS`)
中,评分阈值位于 `app/model.py` (`HIGH_RISK_THRESHOLD`,
`MEDIUM_RISK_THRESHOLD`, `PHISHING_THRESHOLD`) 中。
## 局限性
分类器是在一个包含已标记特征向量的小型合成数据集上训练的,因此它
只是演示了流水线,而不是提供生产级别的准确性。替换为真实的语料库(例如 PhishTank 加上良性抓取)只需
替换 `app/model.py` 中的 `TRAINING_FEATURES` / `TRAINING_LABELS`,或者
将持久化的模型加载到 `PhishingDetector` 中。判定结果是启发式的,可能会
产生假阳性 — 请务必独立验证链接。
标签:AI安全, AMSI绕过, AV绕过, Chat Copilot, FastAPI, Splunk, 二维码识别, 反钓鱼, 威胁检测, 机器学习分类器, 逆向工具