## 这是什么?
PhishGuard 是一个按照商业安全产品标准构建的钓鱼检测系统。它不依赖封锁列表或单一的 ML 模型——每个 URL 都会经过五个独立阶段的分析,结果由自适应贝叶斯聚合器融合,该聚合器能够优雅地处理缺失的阶段。
完整的全栈平台:异步 FastAPI 后端、带有实时阶段进度的 Next.js 14 前端、Docker 基础设施以及完整的测试套件。
## 架构
```
URL INPUT
│
┌──────────────▼──────────────┐
│ Stage 1: URL Intelligence │ ~400ms
│ DNS · WHOIS · SSL · ASN │
│ Typosquatting (Damerau- │
│ Levenshtein) · Homoglyphs │
│ VirusTotal · GSB · OpenPhish│
│ URLHaus · AbuseIPDB │
└──────────────┬──────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────────▼──────┐ ┌────────▼───────┐ ┌──────▼──────────┐
│ Stage 2: │ │ Stage 3: │ │ Stage 4: │
│ Content Intel │ │ Visual Intel │ │ LLM Analysis │
│ │ │ │ │ │
│ Page fetch │ │ Playwright │ │ Claude Opus │
│ Login forms │ │ OCR (EasyOCR) │ │ Attack type │
│ Password fields│ │ Template match│ │ Targeted brand │
│ Obfuscated JS │ │ Logo detection│ │ Chain-of-thought│
│ Cloaking detect│ │ Fake badges │ │ reasoning │
└─────────┬──────┘ └────────┬───────┘ └──────┬──────────┘
└──────────────────┼──────────────────┘
│
┌──────────────▼──────────────┐
│ Stage 5: ML Ensemble │
│ │
│ LightGBM + XGBoost │
│ + CatBoost → LR meta- │
│ learner (76 features) │
│ SHAP explainability │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Adaptive Score Aggregator │
│ │
│ Bayesian fusion with hard │
│ overrides for definitive │
│ threat intel signals │
└──────────────┬──────────────┘
│
VERDICT + RISK SCORE
```
### 阶段权重
| 阶段 | 权重 | 描述 |
|-------|--------|-------------|
| URL 情报 | 20% | DNS, WHOIS, SSL, 威胁情报源, 域名仿冒 |
| 内容分析 | 15% | 页面 DOM, 表单, 脚本, 隐藏检测 |
| 视觉分析 | 20% | 屏幕截图渲染, OCR, 模板匹配 |
| LLM 推理 | 25% | Claude Opus 结构化钓鱼分析 |
| ML 集成模型 | 20% | LightGBM + XGBoost + CatBoost + SHAP |
## 检测能力
| 技术 | 方法 |
|-----------|--------|
| 域名仿冒 (`paypa1.com`, `googel.com`) | 针对品牌列表的 Damerau-Levenshtein 距离 |
| Unicode 同形字 (gοοgle 中的西里尔字母 о) | 易混淆字符映射 (Unicode TR39) |
| 子域名中的品牌冒充 | `paypal.evil.com` → 品牌位置错误检测 |
| DGA / 高熵域名 | Shannon 熵阈值 |
| URL 短链接扩展 | 跟踪重定向链至最终目标 |
| 隐藏伪装 (机器人与人类看到的内容不同) | 双重 user-agent 对比,大小比率分析 |
| 凭据收集表单 | DOM 登录表单 + 密码字段 + 外部 action |
| 视觉钓鱼 (伪造的 Microsoft 365) | Playwright 截图 + 模板匹配 |
| 封锁列表命中 | VirusTotal (70+ 引擎), GSB, OpenPhish, URLHaus |
| 零日钓鱼 (不在任何封锁列表中) | LLM + 视觉 + ML 集成模型 |
## 技术栈
### 后端
| 层级 | 技术 |
|-------|-----------|
| 框架 | FastAPI 0.111 + uvicorn (全面异步) |
| 数据库 | SQLAlchemy async + aiosqlite |
| 缓存 | Redis 主缓存,内存 LRU 备用 |
| DNS | aiodns — 异步并行 A/MX/NS/TXT/DMARC 查询 |
| HTTP | httpx[http2] |
| 视觉 | Playwright + EasyOCR + pytesseract |
| LLM | Anthropic Claude Opus 4.8 → GPT-4 备用 |
| ML | LightGBM + XGBoost + CatBoost + scikit-learn |
| 可解释性 | SHAP TreeExplainer |
### 前端
| 层级 | 技术 |
|-------|-----------|
| 框架 | Next.js 14 (App Router) |
| 语言 | TypeScript (严格模式) |
| 样式 | Tailwind CSS v3 |
| 状态 | React hooks |
| API 客户端 | 类型化 fetch 包装器 |
### 基础设施
| 组件 | 技术 |
|-----------|-----------|
| 容器 | Docker + Docker Compose |
| 代理 | Nginx (路由 `/api/` → 后端, `/` → 前端) |
| CI/CD | GitHub Actions (测试 + 类型检查 + Docker 构建) |
| 安全扫描 | Bandit SAST + pip-audit (每周) |
| 负载测试 | Locust |
## ML 管线
### 特征类别(共 76 个)
| 类别 | 数量 | 示例 |
|----------|-------|---------|
| URL 结构 | 35 | 长度、熵、点号、连字符、`@`、URL 中的 IP、域名仿冒距离、同形字数量、子域名中的品牌 |
| 域名情报 | 15 | 存在时间(天)、注册商、国家、SSL 颁发者、通配符证书、Tranco 前 100 万排名 |
| 内容信号 | 11 | 登录表单、密码字段、外部表单 action、混淆的 JS 数量、iframe 数量 |
| 视觉信号 | 5 | 品牌置信度分数、模板匹配分数、OCR 品牌匹配、伪造的安全徽章 |
| 威胁情报 | 7 | VT 恶意计数、GSB 命中、被 OpenPhish 收录、被 URLHaus 收录、AbuseIPDB 评分 |
| LLM 信号 | 5 | 钓鱼概率、攻击类型编码、目标品牌编码、置信度水平 |
### 集成模型设计
```
URL + stage_results → 76-dim feature vector
│
┌──────────┬──────┴───────┐
▼ ▼ ▼
LightGBM XGBoost CatBoost
│ │ │
└──────────┴──────────────┘
│ OOF probabilities
▼
Logistic Regression meta-learner
│
CalibratedClassifierCV
(isotonic regression)
│
p(phishing) ∈ [0, 1]
```
**关键实现说明:**
- **标签编码自动检测:** v1 数据集通常具有 `label=0 = 钓鱼`(反向的)。`auto_detect_labels()` 会在训练前从 HTTPS 比率推断出正确的方向——防止静默的准确性反转
- **等渗校准 (Isotonic calibration):** 树集成模型会产生过度自信的概率。事后等渗校准可生成真实的概率,这对于跨阶段的分数融合至关重要
- **带 OOF 的堆叠 (Stacking):** 元学习器在折外预测上进行训练,以防止数据泄露
## 项目结构
```
hybrid-phishing-detection/
├── backend/ # FastAPI application
│ ├── app/
│ │ ├── api/v1/ # Endpoints: scan, history, health
│ │ ├── core/ # Config (Pydantic BaseSettings), logging, exceptions
│ │ ├── db/ # SQLAlchemy async models + session
│ │ ├── pipeline/ # Stage 1–5 + orchestrator + aggregator
│ │ ├── schemas/ # Pydantic v2 request/response models
│ │ └── services/ # VT, GSB, DNS, WHOIS, SSL, OpenPhish, URLHaus, AbuseIPDB
│ ├── Dockerfile
│ └── requirements.txt
│
├── frontend/ # Next.js 14 application
│ ├── app/
│ │ ├── page.tsx # Landing page with pipeline stages explained
│ │ └── scanner/page.tsx # Scanner with real-time stage progress
│ ├── components/scanner/
│ │ ├── RiskMeter.tsx # SVG arc gauge (0–100 risk score)
│ │ ├── ScanInput.tsx # URL input + fast/full/deep mode selector
│ │ ├── PipelineProgress.tsx # Live stage animation during scan
│ │ ├── ThreatIntelGrid.tsx # VT / GSB / OpenPhish / URLHaus / AbuseIPDB panels
│ │ ├── LLMAnalysis.tsx # LLM verdict with expandable reasoning chain
│ │ ├── ExplainabilityPanel.tsx # SHAP waterfall chart
│ │ ├── ContentSignals.tsx # Page content analysis results
│ │ ├── IOCPanel.tsx # Indicators of compromise by severity
│ │ └── HistorySidebar.tsx # Recent scans with one-click re-scan
│ ├── lib/
│ │ ├── types.ts # Full TypeScript type system
│ │ └── api.ts # Typed fetch client
│ ├── Dockerfile
│ └── package.json
│
├── ml/ # v2 ML pipeline
│ ├── features/
│ │ ├── url_features.py # 35 pure URL features (no network I/O)
│ │ └── feature_pipeline.py # 76-feature vector builder
│ └── training/
│ └── train_ensemble.py # LightGBM + XGBoost + CatBoost stacking trainer
│
├── infrastructure/
│ ├── docker-compose.yml # Full stack with health checks
│ ├── nginx.conf # Reverse proxy
│ └── .env.example # All env vars documented
│
├── tests/
│ ├── unit/ # URL feature + pipeline helper tests
│ ├── integration/ # Async API tests (pytest-asyncio + httpx)
│ └── load/locustfile.py # Weighted load test
│
├── .github/workflows/
│ ├── ci.yml # Push: test + typecheck + Docker build
│ └── security.yml # Weekly: Bandit SAST + pip-audit
│
└── about/
└── ARCHITECTURE_V2.md # Detailed architecture doc
```
## 扫描模式
| 模式 | 典型耗时 | 活动阶段 |
|------|-------------|--------------|
| **快速 (Fast)** | ~2秒 | URL 情报 + ML 集成模型 |
| **完整 (Full)** | ~8秒 | URL 情报 + 内容分析 + ML 集成模型 |
| **深度 (Deep)** | ~20秒 | 包含视觉和 LLM 在内的所有 5 个阶段 |
## API 参考
### `POST /api/v1/scan`
```
{
"url": "http://paypa1-login-secure.xyz/account",
"mode": "deep",
"follow_redirects": true
}
```
**响应:**
```
{
"scan_id": "3f8a2c1d-...",
"verdict": "PHISHING",
"risk_score": 94.7,
"confidence": 0.96,
"attack_type": "credential_harvesting",
"targeted_brand": "PayPal",
"stages": {
"url_intel": {
"score": 88.0,
"typosquat_target": "paypal",
"threat_intel": {
"virustotal": { "malicious": 34 },
"openphish": { "listed": true }
}
},
"llm": {
"score": 96.0,
"confidence": "high",
"key_indicators": [
"TLD .xyz with brand name in domain",
"Login form submitting to external endpoint"
]
},
"ensemble": {
"score": 91.2,
"top_shap_features": [
{ "feature": "typosquat_min_distance", "shap_value": 0.312, "impact": "increases_risk" }
]
}
},
"iocs": [
{ "type": "domain", "value": "paypa1-login-secure.xyz", "severity": "critical" }
],
"scan_duration_ms": 6842,
"cached": false
}
```
其他 endpoint:`GET /api/v1/history` · `GET /api/v1/health` · `GET /api/v1/ready`
交互式文档:`http://localhost:8000/docs`
## 快速开始
### 选项 A — Docker(推荐)
```
git clone https://github.com/pansariabhijay-source/Hybrid-Phishing-Detection.git
cd Hybrid-Phishing-Detection
cp infrastructure/.env.example .env
# 可选择添加 API keys(均为可选——系统会优雅降级)
docker compose -f infrastructure/docker-compose.yml up --build
```
| 服务 | URL |
|---------|-----|
| 前端 | http://localhost:3000 |
| 后端 API | http://localhost:8000 |
| API 文档 (Swagger) | http://localhost:8000/docs |
### 选项 B — 本地开发
**后端:**
```
cd backend
pip install -r requirements.txt
playwright install chromium
uvicorn app.main:app --reload --port 8000
```
**前端:**
```
cd frontend
npm install
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1 npm run dev
```
### 训练 ML 模型
```
# 将带标签的 CSVs 放入 data/(columns: url, label)
python ml/training/train_ensemble.py \
--phish data/phishing.csv \
--legit data/legitimate.csv \
--output ml/models/ensemble_v2.pkl
```
## 测试
```
# 运行 unit + integration tests
pytest tests/ -v
# Load test(backend 必须正在运行)
pip install locust
locust -f tests/load/locustfile.py --host http://localhost:8000
```
## 环境变量
| 变量 | 必填 | 描述 |
|----------|----------|-------------|
| `VIRUSTOTAL_API_KEY` | 否 | 针对 70+ AV 引擎扫描 URL |
| `GOOGLE_SAFE_BROWSING_API_KEY` | 否 | Google 威胁数据库 |
| `ANTHROPIC_API_KEY` | 否 | 用于 LLM 阶段的 Claude Opus |
| `OPENAI_API_KEY` | 否 | 用于 LLM 阶段的 GPT-4 备用 |
| `ABUSEIPDB_API_KEY` | 否 | IP 信誉评分 |
| `REDIS_URL` | 否 | 缓存后端(退回到内存 LRU) |
| `DATABASE_URL` | 否 | 默认为 `sqlite+aiosqlite:///./phishguard.db` |
所有 API 集成都是可选的。系统会根据可用的阶段自适应调整其评分。
## 为什么做出这些设计选择?
**五个阶段而不是单一模型** — 没有任何单一信号能在所有钓鱼变体中保持可靠。一个新注册的、零 VT 命中记录的相似域名需要 LLM + 视觉检测。而已知的钓鱼工具包则需要封锁列表检测。多阶段处理可以兼顾两者。
**自适应贝叶斯融合** — 在生产环境中,外部 API 会超时,Playwright 可能不可用。当某个阶段缺失时,硬编码的权重会悄无声息地降低结果质量。自适应融合能够无论何种情况都保持分数的校准。
**使用 SHAP 提升可解释性** — 安全分析师需要知道*为什么*某个 URL 会被标记。来自 ML 集成模型的 SHAP 特征归因直接显示在 UI 的判定结果旁边。
**树集成模型的等渗校准** — 树模型默认会过度自信。使用等渗回归进行事后校准可以生成真实的概率而不是分数,这对于多阶段的分数融合至关重要。
## 路线图
- [ ] 通过 Redis pub/sub 实现实时 OpenPhish 情报源
- [ ] 钓鱼工具包指纹识别(模板哈希数据库)
- [ ] 钓鱼检测的 Webhook 告警
- [ ] 包含每日/每周趋势图表的仪表盘
- [ ] 用于 IOC 导出的 MISP 集成
- [ ] 电子邮件标头分析模块
## 许可证
MIT — 查看 [许可证](LICENSE)