WebGuard 是一个使用 Python 和 Flask 开发的单机自托管 Web 安全检测平台,面向本地靶场和明确授权的测试环境。平台完成从任务创建、受控爬取、输入点建模、插件检测、后台执行、证据持久化到报告输出的完整流程。
本项目不会替代专业商业扫描器。自动结果属于风险线索,需要人工确认。禁止对未授权目标进行扫描。
- Flask Application Factory 与 Blueprint 模块化结构
- SQLite + SQLAlchemy 持久化
- 同源递归 Crawler:URL 去重、深度/数量/超时限制、静态资源过滤
- URL 参数和 GET/POST 表单字段提取
- 插件式检测引擎与统一 Finding 模型
- SQL Injection:错误特征、真假条件、动态基线稳定性检查
- Reflected XSS:不可执行标记的原样反射检查
- Security Headers:CSP、nosniff、Referrer-Policy、HSTS、点击劫持防护
- ThreadPoolExecutor 后台任务、状态机、实时进度、取消与重试
- HTML 打印报告与 JSON 结果接口
- CSRF、防点击劫持、CSP、安全 Cookie 和目标白名单
- 独立本地漏洞靶场、安全/不安全对照页面
- Docker Compose 一键部署和健康检查
- 单元、集成与真实 HTTP 端到端测试
flowchart LR
A[创建授权任务] --> B[后台线程池]
B --> C[同源受控爬取]
C --> D[URL/参数/表单建模]
D --> E[插件调度器]
E --> F[SQLi]
E --> G[Reflected XSS]
E --> H[Security Headers]
F --> I[结果去重与持久化]
G --> I
H --> I
I --> J[Web详情/HTML报告/JSON]
更多设计说明见 架构文档。
要求 Python 3.10 或更高版本。
cd D:\WebGuard
.\venv\Scripts\python.exe -m pip install -r requirements.txt终端1启动本地靶场:
.\venv\Scripts\python.exe run_lab.py终端2启动 WebGuard:
.\venv\Scripts\python.exe app.pyapp.py 用于开发调试。Windows 本机长期运行可改用 Waitress:
.\venv\Scripts\python.exe serve.py浏览器访问 http://127.0.0.1:5000,创建目标 http://127.0.0.1:5001,勾选授权确认。任务会自动完成爬取和检测。
复制环境配置并修改密钥:
Copy-Item .env.example .env
docker compose up --build打开 http://127.0.0.1:5000,Docker 内部靶场目标填写:
http://lab:5001
停止服务:
docker compose down扫描数据存放在 webguard_data Docker 数据卷中。docker compose down -v 会同时删除数据卷。
.\venv\Scripts\python.exe -m unittest discover -s tests -v测试覆盖 URL 规范化、同源和资源限制、参数与表单提取、三类插件、安全页面对照、异常隔离、CSRF、报告、状态接口、后台取消,以及真实 HTTP 靶场的完整后台扫描。
| 表 | 用途 |
|---|---|
scan_tasks |
任务状态、时间和错误信息 |
scan_metrics |
进度、阶段和统计数量 |
scan_urls |
Crawler 实际访问的页面 |
scan_inputs |
查询参数与表单字段 |
vulnerabilities |
风险、置信度、证据和修复建议 |
默认数据库为 instance/webguard.db。Docker 使用 /data/webguard.db 和持久化数据卷。
所有部署配置都通过 WEBGUARD_ 环境变量管理,示例见 .env.example。
| 变量 | 默认值 | 说明 |
|---|---|---|
WEBGUARD_ALLOWED_HOSTS |
localhost/回环IP | 明确允许扫描的主机 |
WEBGUARD_CRAWLER_MAX_DEPTH |
2 | 最大爬取深度 |
WEBGUARD_CRAWLER_MAX_PAGES |
50 | 最大请求页面数 |
WEBGUARD_TASK_WORKERS |
2 | 后台并行任务数 |
WEBGUARD_ALLOW_POST |
false | 是否允许自动提交 POST 表单 |
POST 自动检测默认关闭,因为提交表单可能改变目标数据。即使目标在白名单中,也应在隔离环境确认后才启用。
GET /healthz:健康检查GET /scans/<id>/status:实时任务状态GET /scans/<id>/report:可打印 HTML 报告GET /scans/<id>/report.json:结构化结果
- 适合单机或隔离内网中的单用户部署,不是公网多租户 SaaS
- 后台任务使用进程内线程池;Gunicorn 必须保持单 Worker
- SQLite 适合当前受控并发,不适合大规模分布式扫描
- 不执行 JavaScript,不能完整覆盖 SPA 动态路由
- 启发式检测可能误报或漏报,结果必须人工确认
- 当前只实现三类检查,不宣称覆盖全部 OWASP Top 10
- 当前固定结构使用
db.create_all();结构演进应引入 Alembic/Flask-Migrate
WebGuard 默认仅允许本机回环地址,Docker 示例额外允许内部服务名 lab。不要把故意不安全的 lab 服务绑定到公网。详细策略见 SECURITY.md。
webguard/ Flask 主平台
models/ SQLAlchemy 数据模型
routes/ 页面与 JSON 接口
scanner/ 插件接口、调度器和检测插件
services/ 爬虫/检测与数据库业务层
tasks/ 后台线程池和任务状态机
crawler/ 受控递归爬虫
lab/ 故意不安全的本地靶场
tests/ 单元、集成和端到端测试
docs/ 架构与面试材料