naidimwamelynda-sudo/Web-Vulnerability-Scanner-DevSecOps
GitHub: naidimwamelynda-sudo/Web-Vulnerability-Scanner-DevSecOps
一款面向开发者的部署前 Web 安全门禁工具,在本地或 CI 中扫描自有应用并提供带优先级的修复清单,可在存在严重漏洞时阻断部署。
Stars: 0 | Forks: 0
# WebVulnScanner Enterprise
一款**面向开发者的部署前安全门禁** —— 在本地或 CI 中扫描您自己的应用或站点,获取包含具体修复方案的优先级修复清单,并在仍存在严重问题时阻止部署。采用模块化、多线程设计,支持 CVSS/CWE 映射及插件扩展。
不要把它当成用来测试别人站点的渗透测试工具,而要把它看作是在您发布代码前运行的安全漏洞检查工具:将它指向 `localhost`、预发布环境或 PR 预览 URL,它就会确切地告诉您哪里有问题以及如何修复。
## 开发者快速入门
```
# 1. 在本地启动你的 app,然后在 push 前进行扫描
python scanner.py http://127.0.0.1:3000
# 2. 阅读输出底部的 Fix Checklist —— 那就是你的操作清单
# 3. 修复、重新运行、重复,直到 gate 通过
```
## 作为部署前 / CI 门禁使用
```
python scanner.py https://staging.myapp.com \
--ci \
--format sarif json \
--fail-on HIGH
```
- `--ci` 切换为紧凑的、对机器友好的输出(如果设置了 `$CI` 则会自动启用)
- `--fail-on HIGH`(默认)使得当存在任何 HIGH 或 CRITICAL 级别的发现时,命令以非零状态退出 —— 可以使用 `--fail-on CRITICAL` 来放宽限制,或者使用 `--fail-on NONE` 以从不阻止部署
- `--format sarif` 会生成一份 SARIF 2.1.0 报告,GitHub Code Scanning、GitLab 和 Azure DevOps 会将其渲染为内联 PR 批注,而不仅仅是一个您需要记得去打开的文件
`.github/workflows/security-gate.yml` 中包含了一个现成可用的 GitHub Actions 工作流 —— 将其复制到您自己的仓库中,并将 "Start application under test" 步骤指向您的应用即可。
## 相比原版工具的新特性
| 功能 | 原版 | Enterprise 版 |
|---|---|---|
| 架构 | 单个 `scanner.py` 脚本 | 模块化包:`core/`、`checks/`、`reports/`、`plugins/` |
| 并发 | 单线程 | 多线程扫描引擎(`ThreadPoolExecutor`) |
| 爬取 | 基础 | 深度感知的 BFS 爬虫、表单提取、JS endpoint 发现、作用域/排除规则 |
| 漏洞检测 | XSS、SQLi、 headers、重定向(基础) | + SSRF、CSRF、目录遍历、命令注入、敏感文件暴露、cookie 安全、CORS 配置错误 |
| 检测深度 | 单一 payload | 基于错误**和**基于时间的盲注 SQLi/命令注入、多语言 XSS payload、云元数据 SSRF payload |
| 评分 | 无 | CVSS v3.1 分数 + 向量、CWE ID 以及针对每个发现的修复指南 |
| 认证支持 | 无 | Bearer token、cookie、HTTP Basic、自定义 header |
| 容错性 | 基础请求 | 带有指数退避的重试、速率限制、UA 轮换、基于线程的独立会话 |
| 报告 | 仅控制台 | JSON、交互式 HTML 仪表板以及纯文本报告 |
| 扩展性 | 无 | 插件架构 —— 只需在 `plugins/` 目录放入一个 Python 文件 |
| CLI | 最小化 | 完整的 `argparse` CLI:作用域、认证、性能、检测选择、输出控制 |
## 安装说明
```
pip install -r requirements.txt --break-system-packages # or use a virtualenv
```
## 使用说明
```
# Basic 扫描
python scanner.py https://target.com
# 使用自定义 thread count 和完整报告集的 Authenticated 扫描
python scanner.py https://target.com \
--auth-token eyJhbGciOiJIUzI1NiIs... \
--threads 10 \
--format html json txt \
--output report
# Scoped 扫描,跳过 noisy checks,仅限 high+ 严重性
python scanner.py https://target.com \
--depth 5 --max-pages 500 \
--exclude "/logout" "/admin/.*" \
--skip cors cookies \
--min-severity HIGH
# 基于 Cookie 的 session + 自定义 headers
python scanner.py https://target.com \
--cookie "session=abc123; csrftoken=xyz" \
--header "X-Api-Key:secret123" "X-Custom:value"
# 加载自定义 plugin
python scanner.py https://target.com --plugin plugins/example_plugin.py
```
运行 `python scanner.py --help` 获取完整的选项列表(作用域、认证、性能、检测、输出、插件)。
## 检测模块
| 模块 | 检测内容 | CWE |
|---|---|---|
| `xss` | 反射型 XSS(12+ 种 payload,包括多语言、模板注入探测) | CWE-79 |
| `sqli` | 基于错误 + 基于时间的盲注 SQL 注入(MySQL/MSSQL/PostgreSQL/SQLite) | CWE-89 |
| `headers` | 缺失/薄弱的 HSTS、CSP、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy、信息泄露 headers | CWE-693 |
| `redirect` | 通过常见重定向参数进行的开放重定向 | CWE-601 |
| `ssrf` | 通过类似 URL 的参数进行的 SSRF、云元数据 endpoint 探测(AWS/GCP/Alibaba) | CWE-918 |
| `csrf` | 改变状态的 POST 表单中缺失 CSRF token | CWE-352 |
| `traversal` | 路径遍历(`/etc/passwd`、`win.ini`、编码变体) | CWE-22 |
| `cmdi` | OS 命令注入 —— 基于输出和基于时间的盲注 | CWE-78 |
| `sensei` | 暴露的 `.env`、`.git`、备份、私钥、docker-compose 等 | CWE-538 |
| `cookies` | 类会话 cookie 缺失 Secure/HttpOnly/SameSite | CWE-614 |
| `cors` | 通配符 / 反射来源的 CORS 配置错误 | CWE-942 |
每项发现都包含 CVSS v3.1 分数 + 向量、CWE 标识符、证据以及具体的修复指南。
## 扫描需要认证的应用
对于登录后才能访问的内容,您有两个选择:
**您已经有了 token/cookie**(例如,从您的浏览器开发者工具中获取):
```
python scanner.py https://staging.myapp.com --cookie "session=abc123"
# 或
python scanner.py https://staging.myapp.com --auth-token "eyJhbGciOi..."
```
**让 WebX 替您登录。** 它会 GET 登录页面,自动检测隐藏字段(包括 CSRF token),使得发出的 POST 请求看起来像真实的表单提交,并派生出一个用于整个扫描过程的会话 cookie:
```
python scanner.py https://staging.myapp.com \
--login-url https://staging.myapp.com/account/login \
--login-user melynda --login-pass "correcthorsebatterystaple" \
--login-success-text "Dashboard"
```
如果测试账号启用了基于 TOTP 的 MFA,请添加 `--mfa-secret`(base32 种子)、`--mfa-url` 和 `--mfa-field` —— WebX 会使用 `pyotp` 计算当前验证码,并将其作为第二步提交。仅对您实际拥有 MFA 种子的测试账号使用此功能。
交互式菜单通过引导式提示提供了相同的功能(`Scan before deploy` -> 认证问题 -> "log in for me")。
## 团队仪表板 —— 扫描历史与趋势
每次扫描(CLI 或菜单)都会自动记录到本地 SQLite 文件中(默认为 `scan_history.db`)。由于这是一个 CLI 工具而不是托管服务,此处的“团队”意味着:将每个人的 `--history-db` 指向同一个共享路径(同步文件夹、网络驱动器,或作为 CI 构件拉取的文件),这样无需搭建服务器,您就能获得一个共享且可查询的历史记录。
```
python scanner.py --dashboard # all targets, recent scans
python scanner.py https://myapp.com --dashboard # trend for one target
python scanner.py https://myapp.com --history-db /shared/team/scans.db ...
```
交互式菜单的 **Team dashboard** 选项通过丰富的表格和趋势迷你图(`█▅▁` —— 从最旧到最新)展示相同的数据,让您可以一目了然地查看目标的发现在不同扫描之间是呈上升还是下降趋势。
## 编写插件
```
# plugins/my_check.py
from core.finding import Finding
PLUGIN_NAME = "my_check"
def run(client, ep, config):
findings = []
# ep.url, ep.method, ep.params are available
# client.get() / client.post() for additional requests
return findings
```
使用 `--plugin plugins/my_check.py` 加载它。
## 项目结构
```
webvulnscanner-enterprise/
├── scanner.py # CLI entry point
├── core/
│ ├── config.py # ScanConfig dataclass
│ ├── finding.py # Finding dataclass + CVSS table
│ ├── http_client.py # Hardened HTTP client (retries, rate limit, auth)
│ ├── crawler.py # Depth-aware crawler + form extraction
│ ├── engine.py # Multi-threaded scan orchestrator
│ └── results.py # Aggregated results container
├── checks/ # One module per vulnerability class
├── reports/
│ └── reporter.py # JSON / HTML / TXT report generation
├── plugins/
│ └── example_plugin.py # Plugin template
└── test_target.py # Intentionally vulnerable Flask app for self-testing
```
## 在本地验证扫描器
包含了一个故意设计带有漏洞的 Flask 应用(`test_target.py`),覆盖了所有十一个检测模块,以及一个受 CSRF 保护且具备 TOTP-MFA 感知能力的登录流程,该流程保护着一个受限制页面 —— 反射型 XSS、基于错误/时间的 SQLi、OS 命令注入、SSRF、路径遍历、开放重定向、缺失 CSRF token、暴露的 `.env`、配置错误的 CORS、不安全的 cookie、缺失的安全 headers 以及仅认证后才可访问的内容。
**自动化测试套件**(推荐 —— 速度快,并且涵盖了检测和误报规避):
```
pip install -r requirements-dev.txt --break-system-packages
pytest tests/ -v
```
`tests/conftest.py` 会自动启动和停止 `test_target.py`,因此无需手动管理服务器。跨越三个文件的 20 个测试:
- `test_checks.py` —— 每个检测模块的真正阳性检测和误报规避
- `test_auth_flow.py` —— 登录流程功能:感知 CSRF 的表单登录、TOTP MFA、错误凭证拒绝,以及一项端到端检查,验证派生的会话 cookie 是否确实能够解锁并检测到仅认证页面上的漏洞
- `test_history.py` —— 针对团队仪表板的扫描历史记录和趋势方向计算
**手动/全量爬取扫描**,如果您想查看交互式进度条和端到端的修复清单:
```
python test_target.py & # serves on http://127.0.0.1:5050
python scanner.py http://127.0.0.1:5050 --threads 8
```
### 2.0.0 版本以来的修复
针对扩展目标的测试发现并修复了几个真实的 bug,而不仅仅是表面问题:
- **爬虫丢弃了来自 `` 链接的查询字符串参数。** 像 `` 这样的链接在被添加到爬取队列时带有空的 `params` 字典,因此一整类通过 URL 参数进行的基于 GET 的反射型 XSS/SQLi 被默默地漏测了。已在 `core/crawler.py` 中修复。
- **基于时间的盲注 SQLi/命令注入检测使用了单一的绝对阈值**(`elapsed >= 3.5s`),这导致在目标开发服务器上由于普通的线程争用而产生误报。在 `core/timing_probe.py` 中进行了重写,要求提供基于 endpoint 的基准测量加上两点(低延迟、高延迟)确认,因此延迟必须实际追踪注入的 sleep 值,而不仅仅是超过一个固定的数字。
- **HTTP 客户端对每个 500/502/503/504 响应都进行最多 3 次带退避的重试。** 在 fuzzing 过程中,很大一部分 payload 理所当然会产生 500 错误 —— 而对于基于错误的 SQLi 检测,那个 500 *就是* 检测信号。重试它浪费了大量的扫描时间,并导致上述时间测量值虚高。现在重试范围仅限定于 429(速率限制)。
- **速率限制是一个由所有线程共享的全局 50 req/min 瓶颈**,这意味着 `--threads N` 从未真正提高过吞吐量 —— 无论线程数多少,整个扫描过程中的每个请求都被序列化到 1 次/秒以下。默认值提高到了 300 req/min;对于需要温和对待的共享/类生产环境目标的扫描,仍然可以通过 `--rate-limit` 向下配置。
## 法律声明
此工具执行主动的利用尝试(注入 payload、遍历探测等)。未经授权对系统运行此工具可能会违反您所在司法管辖区的计算机犯罪法律(例如美国的 CFAA、英国的 Computer Misuse Act)。仅在您拥有或获得明确授权进行测试的系统上使用。
标签:CISA项目, DAST, DevSecOps, Python, SARIF, Web漏洞扫描, 上游代理, 安全规则引擎, 恶意软件分析, 无后门, 调试插件, 逆向工具