chrispy-02/security-scanner-platform
GitHub: chrispy-02/security-scanner-platform
一个基于 OWASP ZAP 的 Web 应用漏洞扫描平台,通过 Flask 仪表板实现自动化的漏洞检测、结果可视化与基于角色的访问管理。
Stars: 0 | Forks: 0
# 漏洞检测与分析
一个自动化执行 **OWASP ZAP** 扫描、解析结果,并通过交互式、基于角色的仪表板展示漏洞的 Web 应用安全平台。
## 演示登录
部署的演示版本预设了四个角色(密码可通过环境变量配置):
| 角色 | 邮箱 | 密码(默认) | 权限 |
|----------|------------------------|----------------------|--------|
| Owner | `owner@demo.local` | `demo-owner-pass` | 所有权限,包括用户角色管理 |
| Admin | `admin@demo.local` | `demo-admin-pass` | 管理网站、扫描、计划任务以及大多数用户 |
| Employee | `employee@demo.local` | `demo-employee-pass` | 为共享站点运行扫描 / 查看报告 |
| Reader | `reader@demo.local` | `demo-reader-pass` | 对共享站点仅具有查看权限 |
在 `/login` 页面登录(无需 Google 账号)。同时也支持 Google OAuth。
## 截图
| 高管仪表板 | 扫描仪表板 | 角色管理 |
|---|---|---|
|  |  |  |
### 架构

## 功能
- 通过 GitHub Actions pipeline 实现 **OWASP ZAP 扫描自动化**
- **漏洞仪表板**,包含风险摘要(高 / 中 / 低 / 信息)
- **扫描历史记录**以及每次扫描的**报告视图**,包含趋势和修复对比
- **基于角色的访问控制**(owner / admin / employee / reader)
- **定时扫描**(每小时 / 每天 / 每周 / 每月)
- **REST API**,支持每用户 API 密钥
- 使用 **MySQL 持久化**存储解析后的扫描摘要和漏洞记录
- **Docker 化**的本地开发和部署
- **安全的公共演示模式**:扫描目标 allowlist、SSRF 防护、每用户 cooldown
## 技术栈
Flask · MySQL · Docker / Docker Compose · GitHub Actions · OWASP ZAP ·
HTML / CSS / JavaScript · Chart.js · Google OAuth (Authlib) · Gunicorn
## 项目起源
### 针对公共部署所做的改进
- 移除了所有签入的 secrets,并将配置转移到环境变量中
- 将 MSU **GitLab CI** 扫描器依赖项替换为 **GitHub Actions**
- 将扫描自动化迁移到了延迟初始化的后端(导入时不进行网络调用,
因此应用可以在任何地方启动)
- 清理了 Docker / 本地开发环境设置(精简镜像、非 root 用户、镜像中不含 secrets)
- 添加了部署文档(`DEPLOYMENT.md`、`SECURITY.md`、`ARCHITECTURE.md`)
- 添加了带有预设、合成演示数据的演示登录流程
- 添加了安全的扫描目标控制(allowlist + SSRF 验证 + cooldown)
- 移除了未使用的 SocketIO/eventlet,并升级到了 Python 3.12
## 本地运行(Docker)
前置条件:Docker + Docker Compose。
```
cp .env.example .env # then edit values (generate FLASK_SECRET_KEY + FERNET_KEY)
docker compose up --build
```
打开 并使用上方的演示账号登录。该 stack 会启动
MySQL,创建 schema,填充演示数据,并自动运行应用。
生成两个必需的 secrets:
```
python -c "import secrets; print('FLASK_SECRET_KEY=' + secrets.token_hex(32))"
python -c "from cryptography.fernet import Fernet; print('FERNET_KEY=' + Fernet.generate_key().decode())"
```
## 部署指南
请参阅 **[DEPLOYMENT.md](DEPLOYMENT.md)** 了解免费层方案(Render Web 服务 +
Aiven MySQL + 使用 GitHub Actions 进行扫描)、Google OAuth 设置和验证步骤。
## 环境变量
| 变量 | 必需 | 描述 |
|---|---|---|
| `FLASK_SECRET_KEY` | 是(生产环境) | Flask 会话签名密钥 |
| `FLASK_ENV` | 否 | `production`(默认)或 `development` |
| `PORT` | 否 | Web 服务器端口(默认为 `8080`) |
| `MYSQL_HOST` / `MYSQL_PORT` | 是 | 数据库主机 / 端口 |
| `MYSQL_USER` / `MYSQL_PASSWORD` | 是 | 数据库凭据 |
| `MYSQL_DATABASE` | 是 | 数据库名称 |
| `DOCKER_ENV` | 否 | 在容器内设为 `true`(跳过 `.env` 文件加载) |
| `FERNET_KEY` | 是(生产环境) | 用于可逆的会话邮箱加密的密钥 |
| `PASSWORD_SALT` | 推荐 | 用于单向 password/api-key 哈希的 Salt |
| `OAUTH_ID` / `OAUTH_SECRET` | 否 | Google OAuth 客户端(没有它也能登录) |
| `GITHUB_TOKEN` | 否 | 用于实时扫描的 Fine-grained PAT(Actions 读/写) |
| `GITHUB_OWNER` / `GITHUB_REPO` | 否 | 托管扫描工作流的 Repo |
| `GITHUB_WORKFLOW_FILE` | 否 | Workflow 文件名(默认为 `zap-scan.yml`) |
| `GITHUB_REF` | 否 | 运行 workflow 的 Git ref(默认为 `main`) |
| `DEMO_MODE` | 否 | 启用演示数据填充 / 限制 |
| `DEMO_*_PASSWORD` | 否 | 各角色的演示密码 |
| `SCAN_ALLOWLIST` | 否 | 允许演示用户扫描的以逗号分隔的主机列表 |
| `SCAN_COOLDOWN_SECONDS` | 否 | 每个用户两次扫描之间的最小间隔秒数 |
完整模板:[`.env.example`](.env.example)。
## 已知限制(免费层)
- 免费的 Web 主机**在空闲时会休眠** —— 暂停后的第一次请求会很慢。
- 免费主机使用**临时文件系统**:解析后的结果保存在 MySQL 中,但原始的
扫描工件不会在多次部署之间持久化保存在磁盘上。
- 托管的免费 MySQL 有**存储限制**;因此演示数据集特意设置得很小。
- GitHub Actions 的免费账户有**工件保留 / 运行分钟数限制**。
- 在演示版中,实时扫描是**尽力而为**的;仪表板的数据主要来自预设的种子数据。
## 道德扫描声明
**仅扫描您拥有或获得明确测试权限的系统。** 本项目内置了
SSRF 防护和演示 allowlist,但您需要对您的使用方式负责。
请参阅 [SECURITY.md](SECURITY.md)。
标签:Docker, Flask, OWASP ZAP, 安全防御评估, 版权保护, 请求拦截