ericalfonce/webscanner-final-project

GitHub: ericalfonce/webscanner-final-project

一个基于 Python Flask 的 Web 漏洞扫描器,支持自动检测 SQL 注入、XSS 和 HTTP 安全标头缺失并生成含教育内容的 PDF 报告。

Stars: 0 | Forks: 0

# WebScanner — Web 漏洞扫描器 这是一个基于 Python Flask 构建的 Web 漏洞扫描器,专为 ATC 信息与通信技术文凭(2026)开发。用于检测常见的 Web 应用安全问题 —— SQL 注入、跨站脚本攻击 (XSS) 以及缺失的 HTTP 安全标头 —— 同时提供实时扫描进度、针对每项发现的教育性报告以及 PDF 导出功能。 ## 功能 | 模块 | 功能说明 | |---|---| | **SQL 注入** | 针对 URL 参数和 HTML 表单输入进行基于错误、基于布尔型和基于时间盲注的测试(24 个 payload) | | **XSS 检测** | 使用 23 个精选 payload 进行反射型跨站脚本攻击检测;同时测试 URL 参数和表单输入 | | **安全标头** | 检查 7 个关键 HTTP 标头:CSP、HSTS、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy、X-XSS-Protection | | **智能爬虫** | 广度优先链接发现,最多爬取 50 个页面;提取表单、URL 参数,并将爬取范围限定在目标域名内 | | **详细报告** | 为每个漏洞提供针对单项发现的证据、使用的 payload、修复建议和教育背景 | | **PDF 导出** | 下载带有品牌标识的 PDF 扫描报告,包含严重性细分 | | **实时进度** | 实时日志推送,每 2 秒轮询一次;在活跃扫描期间显示动画进度 | | **扫描历史** | 记录每个用户的所有扫描历史,包含状态、持续时间和发现摘要 | | **快速 / 完整模式** | 快速扫描 = 10 个页面,1–3 分钟。完整扫描 = 最多 50 个页面,5–15 分钟 | ## 技术栈 | 层级 | 技术 | |---|---| | Backend | Python 3 · Flask 3.0 · Flask-Login · Flask-WTF (CSRF) | | ORM | SQLAlchemy 2.x | | Database | SQLite (`instance/scanner.db`) | | 扫描 | `requests` · BeautifulSoup4 (`html.parser`) | | PDF | ReportLab 4.x | | Frontend | Bootstrap 5.3 · Bootstrap Icons · Inter font · Vanilla JS | | Auth | bcrypt (cost factor 12) | ## 安装说明 ### 1. 克隆代码仓库 ``` git clone https://github.com/ericalfonce/webscanner-final-project.git cd webscanner-final-project ``` ### 2. 创建虚拟环境 ``` python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate ``` ### 3. 安装依赖 ``` pip install -r requirements.txt ``` ### 4. 运行 ``` python run.py ``` 在浏览器中打开 [http://127.0.0.1:5000](http://127.0.0.1:5000)。 数据库 (`instance/scanner.db`) 会在首次运行时自动创建,并包含两个预置的测试账号。 ## 使用说明 1. **注册** 一个新账号,或使用测试账号登录(见下文) 2. 点击导航栏中的 **新建扫描** 3. 输入目标 URL(例如 `http://localhost/dvwa`) 4. 选择扫描模块:SQLi、XSS、Headers(或同时选择三项) 5. 选择扫描深度:**快速** 或 **完整** 6. 点击 **开始扫描** — 每 2 秒实时更新进度 7. 扫描完成后查看完整报告 8. 点击 **下载 PDF** 获取可分享的报告 ### 测试账号 | 用户名 | 密码 | 备注 | |---|---|---| | `testuser` | `testpass123` | 默认预置账号 | ## 扫描模式 | 模式 | 爬取页面数 | 爬取深度 | 预计耗时 | |---|---|---|---| | **快速** | 最多 10 个 | 1 层 | 1–3 分钟 | | **完整** | 最多 50 个 | 2 层 | 5–15 分钟 | ## 架构 ### 应用工厂模式 本应用使用 Flask 的应用工厂模式(位于 `app/__init__.py` 的 `create_app()`)。扩展(`SQLAlchemy`、`LoginManager`、`CSRFProtect`)在模块级别实例化,并在工厂内部绑定到应用 —— 这允许为测试创建多个应用实例,并避免循环导入。 ### 后台线程扫描运行器 扫描在守护线程 (`threading.Thread`) 中运行,以便 HTTP 响应能立即返回,浏览器可以轮询进度。由于后台线程不继承请求上下文,该线程会手动推入其专属的 Flask 应用上下文 (`app.app_context()`)。进度被存储在 `ScanLog` 行中,浏览器每 2 秒通过 AJAX 轮询一次 `/scanner/status/`。 ### Blueprint 结构 | Blueprint | URL 前缀 | 职责 | |---|---|---| | `auth_bp` | `/auth` | 登录、注册、登出 | | `dashboard_bp` | `/` | 仪表板和首页 | | `scanner_bp` | `/scanner` | 扫描生命周期、进度、结果、PDF、历史记录 | ## 项目结构 ``` webscanner-final-project/ ├── run.py # Entry point — creates app and runs dev server ├── requirements.txt ├── README.md │ ├── app/ │ ├── __init__.py # App factory, extension init, blueprint registration │ ├── config.py # DevelopmentConfig / ProductionConfig │ ├── models.py # User, Scan, Finding, ScanLog (SQLAlchemy ORM) │ │ │ ├── auth/ │ │ ├── routes.py # /auth/register, /auth/login, /auth/logout │ │ └── forms.py # RegistrationForm, LoginForm (Flask-WTF) │ │ │ ├── dashboard/ │ │ └── routes.py # / (dashboard index) │ │ │ ├── scanner/ │ │ ├── routes.py # Scan runner + all /scanner/* routes │ │ ├── crawler.py # Breadth-first crawler (BFS, same-domain scoping) │ │ ├── sqli_scanner.py # SQL Injection: error / boolean / time-based │ │ ├── xss_scanner.py # XSS: reflected payload injection │ │ ├── header_scanner.py # 7 HTTP security headers │ │ ├── analyzer.py # Deduplication and severity sorting │ │ └── reporter.py # ReportLab PDF generation │ │ │ ├── static/ │ │ └── css/style.css │ │ │ └── templates/ │ ├── base.html # Shared layout (Bootstrap 5.3) │ ├── auth/ # login.html, register.html │ ├── dashboard/ # index.html │ ├── scanner/ # new_scan.html, scan_progress.html, results.html, history.html │ └── errors/ # 404.html, 500.html │ ├── data/ │ ├── payloads/ │ │ ├── sqli_payloads.json # 24 SQL Injection payloads │ │ └── xss_payloads.json # 23 XSS payloads │ └── educational/ │ └── vuln_info.json # Educational content per vulnerability type │ └── instance/ └── scanner.db # SQLite database (auto-created, git-ignored) ``` ## 数据库模型 ### `User` | 列名 | 类型 | 备注 | |---|---|---| | `id` | Integer PK | | | `username` | String(64) | 唯一 | | `email` | String(120) | 唯一,以小写存储 | | `password_hash` | String(256) | bcrypt, cost 12 | | `created_at` | DateTime | UTC | ### `Scan` | 列名 | 类型 | 备注 | |---|---|---| | `id` | Integer PK | | | `user_id` | FK → users | | | `target_url` | String(2048) | | | `scan_type` | String(20) | `quick` 或 `full` | | `scan_modules` | String(100) | 逗号分隔:`sqli,xss,headers` | | `status` | String(20) | `pending` → `running` → `completed` / `failed` | | `pages_crawled` | Integer | | | `total_tests` | Integer | | | `started_at` | DateTime | UTC | | `completed_at` | DateTime | UTC | | `error_message` | Text | 失败时设置 | ### `Finding` | 列名 | 类型 | 备注 | |---|---|---| | `id` | Integer PK | | | `scan_id` | FK → scans | 级联删除 | | `vuln_type` | String(20) | `sqli`, `xss`, `header` | | `severity` | String(10) | `high`, `medium`, `low`, `info` | | `title` | String(200) | | | `affected_url` | String(2048) | | | `affected_parameter` | String(200) | | | `payload_used` | Text | 触发该发现的具体 payload | | `evidence` | Text | 响应片段 | | `remediation` | Text | 修复指南 | | `educational_info` | Text | JSON:了解更多链接和解释 | ### `ScanLog` | 列名 | 类型 | 备注 | |---|---|---| | `id` | Integer PK | | | `scan_id` | FK → scans | 级联删除 | | `timestamp` | DateTime | UTC | | `log_level` | String(10) | `info`, `warning`, `error` | | `message` | Text | | ## API 端点 除非特别标注为公开,所有路由均需登录。 | 方法 | 路径 | 描述 | |---|---|---| | GET/POST | `/auth/register` | 注册新账号(公开) | | GET/POST | `/auth/login` | 登录(公开) | | GET | `/auth/logout` | 登出 | | GET | `/` | 仪表板 | | GET/POST | `/scanner/new` | 新建扫描表单 + 提交扫描 | | GET | `/scanner/progress/` | 实时进度页面 | | GET | `/scanner/status/` | JSON 状态(进度页面每 2 秒轮询一次) | | GET | `/scanner/results/` | 完整扫描结果 | | GET | `/scanner/results//pdf` | 下载 PDF 报告 | | GET | `/scanner/history` | 用户所有扫描记录 | | POST | `/scanner/delete/` | 删除某次扫描 | ### `/scanner/status/` 响应格式 ``` { "status": "running", "pages_crawled": 7, "total_tests": 14, "findings_count": 3, "high_count": 1, "medium_count": 2, "low_count": 0, "logs": [ {"level": "info", "message": "Testing: http://target/login", "time": "14:02:33"} ] } ``` ## 配置 `app/config.py` — 通过设置相应的环境变量来覆盖任何默认值: | 设置 | 默认值 | 环境变量 | 描述 | |---|---|---|---| | `SECRET_KEY` | `dev-secret-key-...` | `SECRET_KEY` | Flask session 密钥 — 在生产环境中**必须**更改 | | `DATABASE_URL` | SQLite `instance/scanner.db` | `DATABASE_URL` | 任何兼容 SQLAlchemy 的 URI | | `SCAN_REQUEST_TIMEOUT` | `10` | — | 每次 HTTP 请求的超时秒数 | | `SCAN_REQUEST_DELAY` | `0.5` | — | 请求之间的礼貌延迟(秒) | | `SCAN_MAX_PAGES` | `50` | — | 每次完整扫描爬取的最大页面数 | | `SCAN_CRAWL_DEPTH` | `2` | — | 最大 BFS 深度 | 对于生产环境,请设置 `FLASK_ENV=production` 以启用 `ProductionConfig` (`DEBUG=False`)。 ## 扫描器模块 ### SQL 注入 (`sqli_scanner.py`) 对每个 URL 参数和表单输入应用三种检测技术: 1. **基于错误** — 注入 payload (`'`, `''`, `' OR '1'='1` 等) 并检查响应是否包含 20 多种数据库错误字符串 (`sql syntax`, `ora-`, `sqlite3`, `unclosed quotation mark` 等) 2. **基于布尔型** — 比较真假条件下的响应内容长度 (`AND 1=1` 对比 `AND 1=2`) 3. **基于时间盲注** — 测量在注入 `SLEEP(3)` / `WAITFOR DELAY '0:0:3'` payload 后的响应时间;如果延迟 ≥ 3 秒则标记为漏洞 ### XSS (`xss_scanner.py`) 仅检测反射型 XSS。向 URL 参数和表单字段注入 23 个 payload,并检查原始 payload 是否在未转义的情况下出现在响应 HTML 中。使用 BeautifulSoup 解析 DOM 并验证 payload 未被 HTML 实体编码。 ### 安全标头 (`header_scanner.py`) 检查目标根 URL 上的七个标头: | 标头 | 缺失时的严重性 | |---|---| | `Content-Security-Policy` | High | | `Strict-Transport-Security` | High | | `X-Frame-Options` | Medium | | `X-Content-Type-Options` | Low | | `Referrer-Policy` | Low | | `Permissions-Policy` | Low | | `X-XSS-Protection` | Low | ### 爬虫 (`crawler.py`) 使用 `collections.deque` 进行广度优先搜索 (BFS)。将所有爬取的链接范围限定在目标域名内。提取内容: - 所有 `` 链接 - 所有带有输入字段名称的 `
` action(用于注入测试) - URL 查询参数 ## 安全性实现 - 密码使用 `bcrypt`(cost factor 12)进行哈希处理 - 所有表单均通过 `Flask-WTF` 受 CSRF token 保护 - 用户只能访问他们自己的扫描记录(在 `_get_user_scan` 中进行所有权检查) - 所有输入在扫描或写入数据库前均在服务器端进行验证 - 扫描目标在爬取前会被验证为有效的 `http://` 或 `https://` URL - 生产环境中提供通用的错误页面(不暴露堆栈跟踪) - 全程使用 SQLAlchemy ORM — 无原生 SQL 字符串拼接 ## 推荐的测试目标 | 目标 | 备注 | |---|---| | [DVWA](https://github.com/digininja/DVWA) | Damn Vulnerable Web Application — 最适合 SQLi + XSS | | [OWASP WebGoat](https://github.com/WebGoat/WebGoat) | 基于 Java,涵盖广泛的漏洞类型 | | [HackTheBox](https://www.hackthebox.com) | 仅限您自己处于活跃状态的机器 | | [TryHackMe](https://tryhackme.com) | 引导式的漏洞练习房间 | ## 已知的局限性 - 仅检测反射型 XSS — 无法检测存储型和基于 DOM 的 XSS - 基于时间的 SQLi 检测在缓慢的网络环境下可能会产生误报 - 无 JavaScript 渲染(未使用 Selenium/Playwright) — 严重依赖 JS 的 SPA 可能无法被完全爬取 - 扫描期间禁用了 SSL 证书验证,以便允许测试使用自签名证书的开发/预发布网站 - 单 SQLite — 在未迁移至 PostgreSQL 之前,不适用于多用户的生产环境部署 ## 免责声明 本工具是作为 ATC 信息与通信技术文凭的一部分,出于**教育目的**而开发的。作者不对本软件的任何滥用或造成的损害负责。请仅在您拥有或获得明确书面授权进行测试的系统上使用。 *Arusha Technical College — 信息与通信技术文凭 — 2026*
标签:BeEF, CISA项目, Python Flask, SQL注入检测, Web漏洞扫描器, XSS检测, 安全测试, 攻击性安全, 爬虫, 逆向工具