eliRap1/web-scanner
GitHub: eliRap1/web-scanner
一款基于 Playwright 爬虫和 FastAPI 构建的全栈 Web 漏洞扫描器,能自动化检测十余种常见漏洞并生成专业分析报告。
Stars: 0 | Forks: 0
# Web 漏洞扫描器
一款全栈 DAST(动态应用安全测试)工具,使用真实浏览器爬取目标站点,识别注入点,并根据涵盖 10 多种漏洞类型的 payload 库进行测试。端到端构建:包含浏览器自动化、异步任务队列、REST API、带身份验证的 SPA、PDF/HTML 报告。
## 目录
- [亮点](#highlights)
- [技术栈](#tech-stack)
- [系统架构](#architecture)
- [漏洞覆盖范围](#vulnerability-coverage)
- [快速开始](#quick-start)
- [项目结构](#project-layout)
- [API 接口](#api-surface)
- [工程笔记](#engineering-notes)
- [测试](#testing)
- [路线图](#roadmap)
- [许可与免责声明](#license--disclaimer)
## 亮点
- **无头浏览器爬虫**基于 Playwright 构建 — 捕获网络请求,执行 JavaScript,跟踪 SPA 路由,解析 sitemap,并通过正则提取从 JS 源码中收集 URL。
- **后台任务队列**支持看门狗超时、指数退避重试、卡死扫描的启动恢复,以及每次扫描的持久化日志流。
- **10 多种漏洞类型**采用可插拔的 payload 注册表(XSS、SQLi、NoSQLi、SSTI、XXE、命令注入、SSRF、路径遍历、开放重定向、头部注入)。
- **置信度评分与确认阶段**用于抑制误报 — 包括错误模式匹配、基线对比和基于时间的佐证。
- **带身份验证的扫描** — 通过会话管理器驱动目标登录流程,然后使用捕获的 cookie 扫描受保护的区域。
- **基于角色的身份验证** — bcrypt 哈希凭据、服务端 bearer-token 会话、刷新 + 注销,以及对每个路由进行限制的中间件。
- **HTML 与 PDF 报告** — 通过 Jinja2 渲染发现结果,包含严重性分组、风险评分、payload、证据和修复建议。
- **DFS 漏洞图** — 交互式 React + SVG 可视化扫描爬虫图、可利用路径和集群。
## 技术栈
| 层级 | 技术 |
| ---------------- | ------------------------------------------------ |
| 后端 | Python 3.10+, FastAPI, Uvicorn |
| 爬虫 | Playwright (Chromium) |
| HTTP 测试 | `requests`, `urllib3` |
| 数据库 | SQLite (WAL 友好型 schema, 启用 FK 约束) |
| 认证 | bcrypt (passlib), 不透明 bearer tokens |
| 前端 | React 18, TypeScript, Vite, React Router |
| 报告 | Jinja2 模板, WeasyPrint / pdfkit (PDF) |
| 测试 | pytest + FastAPI TestClient, Vitest + RTL (UI) |
## 系统架构
```
┌────────────────┐ ┌─────────────────────────────────────────────┐
│ React SPA │ REST │ FastAPI │
│ (Vite + TS) │ ─────► │ ├─ auth router (login/register/refresh) │
│ │ │ ├─ scans router (start/progress/logs) │
│ • Dashboard │ ◄───── │ ├─ reports router (HTML / PDF) │
│ • New Scan │ JSON │ └─ auth middleware (Bearer + RBAC) │
│ • Reports │ └──────────────┬──────────────────────────────┘
│ • Vuln Graph │ │
└────────────────┘ ▼
┌──────────────────────┐
│ Job queue + worker │
│ (thread + watchdog) │
└─────────┬────────────┘
│
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌────────────────┐ ┌──────────────┐
│ Playwright │ │ Vulnerability │ │ SQLite │
│ Crawler │ ───► │ Tester │ ───► │ (scans, │
│ (forms, │ │ (10+ payload │ │ forms, │
│ links, JS, │ │ families, │ │ vulns, │
│ SPA routes) │ │ confidence │ │ logs, │
│ │ │ scoring) │ │ reports) │
└──────────────┘ └────────────────┘ └──────────────┘
```
请求生命周期:
1. UI 提交扫描请求 → 路由器验证 URL(防御 SSRF)并将任务加入队列。
2. 后台 worker 拉取任务,驱动 Playwright,持久化发现的表单/URL。
3. 漏洞测试器遍历每个注入点,发送 payload,并对响应进行评分。
4. 发现结果流式传入 SQLite;UI 每 2 秒轮询进度/日志并渲染结果。
5. 用户可以根据任何已完成的扫描生成 HTML/PDF 报告。
## 漏洞覆盖范围
| 类型 | Payloads | 检测技术 |
| ------------------- | :------: | ---------------------------------------------------- |
| XSS | 16 | 反射匹配,上下文感知 (HTML/attr/JS) |
| SQL 注入 | 18 | 错误字符串指纹,布尔差异,基于时间 |
| NoSQL 注入 | 12+ | 操作符注入,布尔差异 |
| SSTI | 8+ | 引擎特定标记 (Jinja2/Twig/Velocity/Mako) |
| XXE | 5+ | 文件泄露标记 |
| 命令注入 | 10+ | 输出标记 + 基于时间的佐证 |
| SSRF | 15+ | 状态 / Banner 指示符 |
| 路径遍历 | 20 | `/etc/passwd`, Windows 路径, 编码绕过 |
| 开放重定向 | 8 | Location 头,双斜杠,协议相对路径 |
| 头部注入 | 5 | CRLF,响应分割 |
每条发现记录均包含 payload、响应证据、匹配的指示符、置信度评分 (0.0–1.0) 以及严重程度级别。
## 快速开始
### 前置条件
- Python 3.10+
- Node.js 18+
- 你拥有或被授权扫描的目标
### 后端
```
cd app
python -m venv .venv
source .venv/bin/activate # PowerShell: .venv\Scripts\Activate.ps1
pip install -r ../requirements.txt # or: pip install fastapi uvicorn playwright requests passlib[bcrypt] python-multipart jinja2
playwright install chromium
uvicorn main:app --reload --port 8000
```
API 服务地址为 `http://localhost:8000` (Swagger UI 位于 `/docs`)。
### 前端
```
cd web-scanner-ui
cp .env.example .env # then edit VITE_API_URL if not localhost:8000
npm install
npm run dev
```
UI 访问地址为 `http://localhost:5173`。
### 首次登录
后端在首次启动时会引导创建一个管理员账户。在启动前请设置
`WEB_SCANNER_ADMIN_PASSWORD`(以及可选的 `WEB_SCANNER_ADMIN_USERNAME` / `..._EMAIL`)
——如果没有设置,服务器将拒绝启动。对于一次性的开发
实例,你可以设置 `WEB_SCANNER_DEV=1` 以使用不安全的默认
账户 `admin / Admin@123`;切勿在生产环境中执行此操作。
### 环境变量
| 变量 | 位置 | 用途 |
| ------------------------------- | -------- | ------------------------------------------------------------- |
| `WEB_SCANNER_DB` | 后端 | 覆盖 SQLite 路径 (测试时也会用到) |
| `WEB_SCANNER_ADMIN_PASSWORD` | 后端 | 引导首个管理员所必需 (或者设置 `WEB_SCANNER_DEV=1` 以使用不安全的开发默认值) |
| `WEB_SCANNER_ADMIN_USERNAME` | 后端 | 覆盖默认管理员用户名 (`admin`) |
| `WEB_SCANNER_ADMIN_EMAIL` | 后端 | 覆盖默认管理员邮箱 |
| `WEB_SCANNER_DEV` | 后端 | 设置为 `1` 以允许不安全的默认管理员密码 (仅限开发环境) |
| `ALLOWED_ORIGINS` | 后端 | 逗号分隔的 CORS 白名单 (默认: localhost:5173) |
| `VITE_API_URL` | 前端 | SPA 的 API 基础 URL |
## 项目结构
```
web-scanner/
├── app/ # FastAPI backend
│ ├── main.py # ASGI entry, lifespan, CORS, middleware
│ ├── api/auth/{login,register}.py # Auth endpoints
│ ├── security/middleware.py # Bearer-token middleware + public allowlist
│ ├── db/{database,db_utils,backup}.py
│ ├── scans/scans_router.py # Start / progress / logs / vulns / graph
│ ├── reports/{generator,reports_router,remediation}.py
│ └── scanner/
│ ├── engine.py # Playwright crawler
│ ├── vulnerability_tester.py # Payload runner + confidence scoring
│ ├── task_queue.py # Job queue + watchdog + retries
│ ├── worker.py # Background worker thread
│ ├── extractor.py # Form / link / JS-URL extraction
│ ├── scope.py # In-scope URL filter
│ ├── http_client.py # Per-target HTTP helpers
│ ├── auth_manager.py # Target login flows
│ ├── graph_analyzer.py # DFS / cycle / cluster analysis
│ └── payloads/ # One module per vuln class
├── web-scanner-ui/ # React + TypeScript SPA
│ └── src/
│ ├── api/client.ts # apiFetch + token handling
│ ├── components/{Sidebar,VulnerabilityGraph}.tsx
│ └── pages/{Login,Register,Dashboard,NewScan,Reports}.tsx
├── tests/ # pytest suites (unit + integration)
├── reports/ # Generated HTML/PDF (gitignored)
├── pytest.ini
└── README.md
```
## API 接口
| 方法 | 路径 | 描述 |
| ------ | --------------------------------- | ------------------------------------------ |
| POST | `/login` | 用户名/密码 → bearer token |
| POST | `/register` | 创建用户 |
| POST | `/refresh` | 轮换 token |
| POST | `/logout` | 吊销 token |
| GET | `/verify` | Token 内省 |
| GET | `/scan/list` | 列出扫描 (经 RBAC 过滤) |
| POST | `/scan/` | 开始扫描 (JSON body,经验证的 URL,受 SSRF 防护) |
| GET | `/scan/{job_id}` | 最终结果 |
| GET | `/scan/{job_id}/progress` | 实时进度 |
| GET | `/scan/{job_id}/logs` | 持久化日志流 |
| GET | `/scan/{job_id}/vulnerabilities` | 发现详情 |
| GET | `/scan/{job_id}/graph` | DFS 图 payload (节点 / 边 / 环) |
| GET | `/reports/` | 列出报告 |
| POST | `/reports/generate/{scan_id}` | 渲染 HTML + PDF |
| GET | `/reports/view/{report_id}` | 内嵌 HTML |
| GET | `/reports/download/{report_id}` | 下载文件 |
完整的 schema 可在后端运行时通过 `/docs` (Swagger) 和 `/redoc` 浏览。
## 工程笔记
- **SSRF 防御** — `/scan/` 会解析目标主机并拒绝任何落入环回 / 私有 / 链路本地 / 多播 / 保留空间内的地址,同时屏蔽众所周知的元数据主机名。代理 URL 被限制为 `http(s)`。
- **凭据不进入 URL** — 扫描目标凭据仅通过 JSON body 接收;用于报告下载/查看的 JWT 在 `Authorization` 头中发送(SPA 将文件作为 Blob 获取并在本地提供服务),因此 token 永远不会出现在浏览器历史记录、referer 链或访问日志中。
- **协作式取消** — 看门狗在使卡死任务失败之前会翻转 `threading.Event`;爬虫在页面之间检查它,测试器在目标之间检查它,因此 Playwright 可以干净地关闭,而不是泄露浏览器进程。
- **线程安全的 payload 运行器** — 漏洞测试器的并行模式使用每个线程的 `requests.Session`(通过 `threading.local`);没有共享状态会被多个 worker 修改。
- **仅限 Bcrypt 的密码存储** — 遗留的 SHA-256 回退路径已移除;缺少 `passlib[bcrypt]` 会导致硬性启动失败。
- **不泄露堆栈跟踪** — `5xx` 响应返回通用消息;完整的异常记录在服务器端。
- **弹性机制** — 启动恢复会遍历 `Scans` 中的 `running` 行并将其标记为 `failed`;新的扫描随后将从干净的状态开始。完成的任务会在 TTL 后从内存映射中清理,因此队列映射不会无限增长。
- **Payload 注册表**由 `dataclass` 驱动 — 添加新的漏洞类型只需一个包含 `Payload(...)` 条目和 `confirmation` 可调用对象的单一文件;其他无需更改。
- **置信度评分**使用信号复合:编码检测、基线大小增量、特定于数据库的错误模式,以及带有 payload 变体的确认重新测试。
## 测试
```
# Backend (在 app/ venv 中,从 repo root)
pytest
# Frontend
cd web-scanner-ui
npm run test:run
```
后端测试使用 `WEB_SCANNER_DB` 指向每个测试专用的 SQLite 路径,并使用 `FastAPI TestClient` 对完整扫描流程进行集成覆盖。前端测试在 jsdom 中通过 Vitest + Testing Library 运行。
## 路线图
- [ ] 将队列/状态持久化到 Redis,以便扫描能够幸免于重启并实现水平扩展。
- [ ] 兼容 OWASP ZAP 的报告导出。
- [ ] 针对每个目标的速率限制与礼貌控制。
- [ ] 超越 Cookie 捕获的带身份验证扫描流程(OAuth、SSO)。
- [ ] CI 工作流 (GitHub Actions) 在 PR 上运行 `pytest` + `npm run test:run`。
## 许可与免责声明
仅限用于**教育和授权的安全测试目的。** 未经授权的扫描可能会违反您所在司法管辖区的计算机滥用法。在将此工具指向您不拥有的任何系统之前,您有责任获得许可。
标签:AV绕过, CISA项目, DAST, DFS图, FastAPI, Homebrew Cask, HTML报告, HTTP头注入, NoSQL注入, PDF报告, Playwright, React, SPA, SSRF, SSTI, Syscalls, TypeScript, Web安全, XSS, XXE, 前端安全, 动态应用安全测试, 单页应用, 后端安全, 命令注入, 安全插件, 开放重定向, 恶意软件分析, 扫描器, 无头浏览器, 漏洞图谱, 漏洞情报, 特征检测, 网络安全, 蓝队分析, 负载注入, 路径穿越, 逆向工具, 隐私保护