taguianas/PhishGuard_AI-Powered_Phishing_Detection
GitHub: taguianas/PhishGuard_AI-Powered_Phishing_Detection
一个端到端的安全平台,通过多技术融合实现 URL 与邮件的钓鱼威胁检测与用户隔离。
Stars: 0 | Forks: 0
# 🛡️ PhishGuard
### 由 AI 驱动的网络钓鱼检测平台
*启发式规则 · 威胁情报 · 机器学习 · LLM 分析 · 完整认证*
**作者:[Anas TAGUI](https://github.com/taguianas)**
### 🌐 [实时演示](https://phishguard-frontend-7ir8.onrender.com)
一个用于分析 URL 和电子邮件网络钓鱼威胁的全栈网络安全平台,结合了启发式规则、域名仿冒检测、威胁情报 API、训练有素的 XGBoost 分类器以及基于 LLM 的电子邮件分析,所有这些都位于具有用户级数据隔离的完整用户认证系统之后。
## 架构
```
phish-guard/
├── frontend/ Next.js 16.1.6 (App Router) + TailwindCSS + NextAuth.js v5
├── backend/ Node.js + Express API (JWT-protected)
├── ml-service/ Python FastAPI + XGBoost (trained model included)
├── browser-extension/ Chrome Manifest V3 extension
└── tests/ End-to-end test suite (Python)
```
**数据存储:**
- `backend/data/phishguard.db`:SQLite 扫描历史记录(`url_scans`、`email_scans`),按用户过滤
- **Neon PostgreSQL**:用户账户(通过 `bcrypt` 加密的邮箱/密码,Google OAuth)— 在部署期间持久化保存
## 当前状态
| 服务 | 端口 | 状态 |
|---------|------|-------|
| Frontend (Next.js 16) | 3000 | 就绪:已启用认证 |
| Backend (Express) | 4000 | 就绪:受 JWT 保护 |
| ML Service (FastAPI) | 8000 | 就绪:模型已训练 |
## 快速开始
### 1. Backend
```
cd backend
cp .env.example .env # fill in API keys + NEXTAUTH_SECRET
npm install
npm run dev # http://localhost:4000
```
### 2. ML Service
```
cd ml-service
pip install -r requirements.txt
# 构建数据集(自动下载约 789k 钓鱼 URL)
python build_dataset.py # creates data/urls.csv (100k rows)
# 训练模型
python train_model.py # creates model.pkl
# 启动 API
python -m uvicorn main:app --port 8000
```
### 3. Frontend
```
cd frontend
cp .env.local.example .env.local # fill in NEXTAUTH_SECRET (same as backend)
npm install
npm run dev # http://localhost:3000
```
## 用户认证
PhishGuard 需要用户账户才能访问任何页面或 API endpoint。
- **邮箱 + 密码**注册和登录(通过 `bcrypt` 加密,存储在 Neon PostgreSQL 中)
- **Google OAuth**:在 `frontend/.env.local` 中设置 `GOOGLE_CLIENT_ID` 和 `GOOGLE_CLIENT_SECRET` 进行启用
- **Session 策略:**JWT(NextAuth v5,`authjs.session-token` cookie)
- **路由保护:**Next.js middleware 会将未认证的请求重定向到 `/login`,并保留 `?callbackUrl`
- **后端保护:**每个 Express 路由都会使用共享的 `NEXTAUTH_SECRET` 验证来自 `Authorization: Bearer
` 的 JWT
- **数据隔离:**每个用户只能看到自己的扫描历史记录:所有查询都会根据 `user_id` 进行过滤
### 认证流程
```
Browser Next.js (3000) Express (4000)
|-- POST /api/auth/register -->| |
|<-- 201 {"ok":true} ----------| |
|-- POST /api/auth/callback -->| |
|<-- authjs.session-token ckv--| |
|-- POST /api/analyze/url ---->| |
| getToken() |-- Bearer ------->|
| |<-- analysis JSON -------|
|<-- analysis JSON ------------| |
```
前端代理路由(`/api/analyze/*`)在服务端使用 `getToken()` 提取 session token,并使用 `jose` 重新签发兼容后端的 JWT。原始 token 永远不会到达浏览器。
## API Endpoints
### Frontend 代理(端口 3000):需要 session cookie
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| POST | `/api/analyze/url` | 分析 URL(代理至后端,添加认证 header) |
| POST | `/api/analyze/email` | 分析邮件内容(代理至后端) |
| GET | `/api/analyze/history` | 获取用户的扫描历史记录 |
| GET | `/api/analyze/history?type=stats` | 获取用户的扫描统计数据 |
| POST | `/api/auth/register` | 注册新账户 |
| GET/POST | `/api/auth/[...nextauth]` | NextAuth.js 处理程序(登录、session、退出登录、CSRF) |
### Backend(端口 4000):需要 `Authorization: Bearer `
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| POST | `/api/url/analyze` | 分析 URL 的钓鱼风险 |
| POST | `/api/email/analyze` | 分析邮件内容 |
| GET | `/api/history` | 用户扫描历史记录 |
| GET | `/api/history/stats` | 用户汇总统计数据 |
| GET | `/health` | 健康检查(公开) |
### ML Service(端口 8000):公开(内部使用)
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| POST | `/predict` | 对 URL 进行分类(返回预测结果 + 概率 + 特征) |
| GET | `/health` | 健康检查 + 模型加载状态 |
#### URL 分析:响应示例
```
{
"url": "http://paypa1.com/login",
"risk_score": 65,
"classification": "Medium Risk",
"reasons": [
"Suspicious keyword(s): login",
"Not using HTTPS",
"Possible typosquatting of \"paypal\" (distance: 1)",
"Blacklisted by VirusTotal (9 engines)"
],
"threat_intel": { "malicious": 9, "suspicious": 1, "harmless": 58, "blacklisted": true },
"ml_prediction": { "prediction": "Phishing", "probability": 1.0 }
}
```
#### ML 预测:响应示例
```
{
"url": "http://paypa1-security-update.com/login",
"prediction": "Phishing",
"probability": 1.0,
"features": { "is_https": 0, "has_suspicious_tld": 0, "suspicious_keyword_count": 2, "brand_impersonation": 1 }
}
```
## ML 服务:数据集与模型
### 数据集 (`data/urls.csv`)
由 `build_dataset.py` 使用两个数据源构建:
| 来源 | 数量 | 标签 |
|--------|-------|-------|
| [Phishing.Database](https://github.com/mitchellkrogza/Phishing.Database)(活跃的钓鱼 URL) | 50,000 | 1(钓鱼) |
| 由 100 个已知可信域名(Google、GitHub、PayPal 等)生成 | 50,000 | 0(合法) |
| **总计** | **100,000** | 均衡 |
### 模型 (`model.pkl`)
| 属性 | 值 |
|----------|-------|
| 算法 | XGBoost(200 个评估器,深度 6) |
| 特征 | 20 个 URL 结构特征 |
| 测试准确率 | 100%(20,000 个保留样本) |
| 训练/测试集划分比例 | 80/20,分层抽样 |
### 提取的特征
`url_length`、`hostname_length`、`path_length`、`num_dots`、`num_hyphens`、`num_underscores`、`num_slashes`、`num_question_marks`、`num_equals`、`num_at`、`num_percent`、`num_ampersand`、`has_ip`、`is_https`、`has_www`、`has_encoded_chars`、`suspicious_keyword_count`、`has_suspicious_tld`、`subdomain_count`、`brand_impersonation`
## 环境变量
### Backend `.env`
| 变量 | 描述 |
|----------|-------------|
| `PORT` | 后端端口(默认为 4000) |
| `NEXTAUTH_SECRET` | **必填**:共享的 JWT 密钥(与前端值相同) |
| `VIRUSTOTAL_API_KEY` | VirusTotal v3 API key |
| `GOOGLE_SAFE_BROWSING_API_KEY` | Google Safe Browsing API key(免费,每天 1 万次请求) |
| `ML_SERVICE_URL` | ML 微服务 URL(默认为 `http://localhost:8000`) |
| `ALLOWED_ORIGINS` | 逗号分隔的允许的 CORS 源 |
| `GROQ_API_KEY` | 用于 LLM 邮件分类的 Groq API key(在 console.groq.com 免费获取) |
### Frontend `.env.local`
| 变量 | 描述 |
|----------|-------------|
| `NEXTAUTH_SECRET` | **必填**:共享的 JWT 密钥(与后端值相同) |
| `NEXTAUTH_URL` | 前端 URL(默认为 `http://localhost:3000`) |
| `BACKEND_URL` | 用于服务端代理路由的后端 URL(默认为 `http://localhost:4000`) |
| `DATABASE_URL` | **必填**:用于用户账户的 Neon PostgreSQL 连接字符串 |
| `GOOGLE_CLIENT_ID` | Google OAuth 客户端 ID(留空则禁用 Google 登录) |
| `GOOGLE_CLIENT_SECRET` | Google OAuth 客户端密钥 |
| `NEXT_PUBLIC_GOOGLE_ENABLED` | 设为 `true` 以显示 Google 登录按钮 |
### 生成 NEXTAUTH_SECRET
```
openssl rand -base64 32
```
在 `backend/.env` 和 `frontend/.env.local` 中使用相同的值。
### 获取 Google Safe Browsing API Key(免费)
1. 前往 [console.cloud.google.com](https://console.cloud.google.com)
2. 创建一个项目(或选择现有项目)
3. 搜索 **"Safe Browsing API"** 并点击 **启用**
4. 前往 **凭据 → 创建凭据 → API 密钥**
5. 将密钥复制到 `backend/.env` 中作为 `GOOGLE_SAFE_BROWSING_API_KEY`
免费配额:**每天 10,000 次请求**:无需绑定付款信息。
## Render 部署
包含了一个 `render.yaml` 文件,用于将所有三个服务(前端、后端、ML 服务)一键部署到 [Render](https://render.com)。
首次部署后,在 Render 控制台中设置这些环境变量:
| 服务 | 变量 | 值 |
|---------|----------|-------|
| Frontend | `BACKEND_URL` | `https://phishguard-backend.onrender.com`(末尾不要加斜杠) |
| Frontend | `DATABASE_URL` | 您的 Neon PostgreSQL 连接字符串 |
| Frontend | `NEXTAUTH_SECRET` | 与后端相同的密钥 |
| Frontend | `NEXTAUTH_URL` | `https://phishguard-frontend.onrender.com` |
| Backend | `NEXTAUTH_SECRET` | 与前端相同的密钥 |
| Backend | `ALLOWED_ORIGINS` | `https://phishguard-frontend.onrender.com` |
| Backend | `ML_SERVICE_URL` | `https://phishguard-ml.onrender.com` |
| Backend | `VIRUSTOTAL_API_KEY` | 您的 VirusTotal API key |
| Backend | `GOOGLE_SAFE_BROWSING_API_KEY` | 您的 Safe Browsing API key |
| Backend | `GROQ_API_KEY` | 您的 Groq API key |
## 风险评分公式
### URL 评分
| 信号 | 分数 |
|--------|--------|
| IP 地址作为主机名 | +20 |
| URL 长度 > 75 个字符 | +10 |
| 子域名过多 | +10 |
| 可疑关键词 | +5–15 |
| 可疑顶级域名 (TLD) | +15 |
| 无 HTTPS | +10 |
| 检测到域名仿冒 | +25 |
| 编码字符 | +10 |
| VirusTotal 黑名单 | +25 |
| 新注册域名(<1 年) | +10 |
| 被 Google Safe Browsing 标记 | +20 |
分数范围:0–100。分类:低(<40),中(40–69),高(≥70)。
### 邮件评分
启发式算法会检查紧急用语、可疑 URL、语法异常、伪造的发件人域名以及常见的钓鱼关键词。Groq LLM(Llama 3.1 70B)提供独立的判定:如果它以 ≥70% 的置信度将其分类为钓鱼邮件,将额外增加 15 分。
## 测试
### 端到端测试套件
```
# 必须先运行所有三个服务
python tests/e2e_test.py
```
涵盖 8 个组共 57 个测试用例:
1. 服务健康检查(全部 3 个服务)
2. ML URL 预测(钓鱼、合法、无效输入)
3. 后端 401 强制执行(所有受保护的路由)
4. 前端认证流程(注册、登录、session、退出登录)
5. 已认证的代理路由(URL 分析、邮件分析、历史记录、统计)
6. 代理路由:未认证(重定向至登录)
7. 路由保护:页面重定向(所有受保护的页面)
8. 数据隔离(两个用户无法看到彼此的历史记录)
查看 `tests/REPORT.md` 获取完整的测试报告。
## 安全说明
- 通过 `express-validator` 和 Pydantic 对所有 endpoint 进行输入验证
- 频率限制:每个 IP 每分钟 60 次请求(后端)
- Helmet.js 安全标头
- 绝不抓取 URL:仅分析其结构(防止 SSRF 攻击)
- 使用 `bcrypt` 加密密码(12 轮)
- 使用 `HS256` 签名 JWT,并在每次后端请求时进行验证
- API key 存储在 `.env` / `.env.local` 中:切勿提交它们
- 前端代理路由在服务端添加 `Authorization`:原始 JWT 永远不会到达浏览器
## 路线图
- [x] 后端启发式 URL 分析器
- [x] 域名仿冒检测(Levenshtein 距离)
- [x] VirusTotal 威胁情报集成
- [x] 邮件钓鱼分析器
- [x] ML 分类器(XGBoost,基于 10 万个 URL 训练)
- [x] FastAPI ML 微服务
- [x] Next.js 前端(URL 分析器、邮件分析器、仪表盘)
- [x] 域名年限查询(通过 `whoiser` 查询 WHOIS)
- [x] Google Safe Browsing API 集成
- [x] SQLite 扫描历史记录(按用户隔离)
- [x] 带有统计信息和最新扫描表格的实时仪表盘
- [x] 基于 LLM 的邮件分类(Groq:Llama 3.1,免费层级)
- [x] 邮件分析器中的语法异常检测
- [x] Chrome 浏览器扩展(Manifest V3)
- [x] 用户认证(NextAuth.js v5:/密码 + Google OAuth)
- [x] 端到端测试套件(57 个测试,全部通过)
- [x] Render 部署(`render.yaml`:前端 + 后端 + ML 服务)
- [x] Neon PostgreSQL,用于在多次部署中持久化保存用户账户标签:Apex, 全栈开发, 威胁情报, 开发者工具, 机器学习, 浏览器扩展, 网络安全, 自动化攻击, 钓鱼检测, 隐私保护