A full-stack Flask web application for performing safe, read-only security assessments of websites you own or are explicitly authorized to test. It combines a scanner engine (10 passive check modules), a SQLite-backed dashboard, and automated HTML/PDF report generation into a single self-hosted tool.
⚠️ Authorized use only. This tool is intended solely for security assessments of websites you own or have explicit written permission to test. It performs no exploitation, no destructive actions, and no denial-of-service testing — but scanning a system without authorization may still be illegal in your jurisdiction. You are responsible for how you use it.
Scanner Modules (all passive / read-only)
- Information Gathering — domain, resolved IP, reverse DNS hosting hints, HTTP status, response time
- Technology Fingerprinting — server software, CMS detection, JS libraries, framework headers
- Security Header Analyzer — CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, X-Content-Type-Options, Cache-Control
- SSL/TLS Analyzer — certificate issuer/subject, expiry countdown, negotiated TLS version
- Cookie Security — Secure, HttpOnly, SameSite flags per cookie
- robots.txt / sitemap.xml Discovery
- HTTP Response Analyzer — redirect chains, compression, caching headers
- Form Discovery — GET/POST forms, input fields, password fields, CSRF token heuristics
- Reflection Check — passive, marker-based indicator of unescaped input reflection
- Basic SQL Error Detection — benign-input heuristic for leaked DB error messages
Platform
- Session-based authentication (Flask-Login + bcrypt password hashing)
- Projects → Scans → Findings → Reports data model (SQLite)
- Concurrent scan execution via
ThreadPoolExecutor, run in a background thread per scan - Live scan progress polling (JSON endpoint + JS polling, no page reload needed)
- Dashboard with severity breakdown chart (Chart.js), recent activity feed, top risks
- One-click HTML and PDF report generation (Jinja2 + ReportLab)
- Rotating file logs split by concern: application, errors, scans, reports, authentication
- Dark, responsive, animated-sidebar UI built on Bootstrap 5 + Bootstrap Icons
Python 3.12 · Flask · Flask-Login · SQLite · Jinja2 · Bootstrap 5 · Chart.js · Requests · BeautifulSoup4 · socket/ssl (stdlib) · ReportLab · bcrypt · python-dotenv · gunicorn
web-vulnerability-scanner/
├── app.py # Flask application factory / entry point
├── config.py # Centralized typed configuration (reads .env)
├── database.py # SQLite connection management + schema init
├── models.py # Data-access layer (all SQL lives here)
├── requirements.txt
├── .env.example # Copy to .env and edit before running
│
├── scanner/ # Scanner engine
│ ├── base.py # Finding dataclass, shared HTTP helpers
│ ├── engine.py # Orchestrates all modules via ThreadPoolExecutor
│ ├── info_gathering.py
│ ├── tech_fingerprint.py
│ ├── security_headers.py
│ ├── ssl_analyzer.py
│ ├── cookies.py
│ ├── robots_sitemap.py
│ ├── http_analyzer.py
│ ├── forms.py
│ ├── reflection.py
│ └── sql_errors.py
│
├── routes/ # Flask blueprints
│ ├── auth.py # login / logout / register
│ ├── dashboard.py
│ ├── projects.py
│ ├── scan.py # start scan, status polling, history, delete
│ ├── reports.py # generate + download HTML/PDF reports
│ └── settings.py
│
├── utils/
│ ├── logger.py # Rotating file log configuration
│ ├── validators.py # URL / username / email / password validation
│ └── report_generator.py # HTML (Jinja2) + PDF (ReportLab) report builders
│
├── templates/ # Jinja2 templates (dark theme, Bootstrap 5)
│ ├── base.html
│ ├── login.html / register.html
│ ├── dashboard.html
│ ├── projects.html / new_project.html / project_detail.html
│ ├── scan_results.html / scan_history.html
│ ├── reports_list.html
│ ├── settings.html
│ └── errors/404.html / errors/500.html
│
├── static/
│ ├── css/style.css # Full dark cybersecurity theme
│ └── js/sidebar.js, scan_status.js
│
├── database/ # SQLite .db file created here at runtime
├── reports/ # Generated HTML/PDF reports saved here
├── logs/ # Rotating log files saved here
└── exports/ # Reserved for future export features
Requirements: Python 3.12+, pip
# 1. Clone / copy the project, then move into it
cd web-vulnerability-scanner
# 2. Create and activate a virtual environment
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Create your environment file
cp .env.example .env
# Edit .env: set a real SECRET_KEY and change DEFAULT_ADMIN_PASSWORD
# 5. Run the app (development)
python app.pyThe app will:
- Auto-create the SQLite database at
database/scanner.dbon first run - Auto-create
reports/,logs/, andexports/directories if missing - Seed a default admin account using
DEFAULT_ADMIN_USERNAME/DEFAULT_ADMIN_PASSWORDfrom.env
Visit http://127.0.0.1:5000 and log in with your configured admin credentials. Change the default admin password immediately after first login (via the registered account flow, or by registering a new account and retiring the seeded one).
gunicorn -w 4 -b 0.0.0.0:5000 app:appPut a reverse proxy (nginx, Caddy) in front of gunicorn for TLS termination, and set SESSION_COOKIE_SECURE=True in .env (already the default) once served over HTTPS.
- Register / log in.
- Create a Project — give it a name and the target URL you're authorized to test.
- Start a Scan from the project page. It runs in the background; the results page polls live and updates automatically.
- Review Findings — grouped and color-coded by severity (High / Medium / Low / Info), each with a description, recommendation, and supporting evidence.
- Generate a Report — click "Generate HTML" or "Generate PDF" from a completed scan's results page, then download it from the same page or the global Reports list.
- Adjust Settings — company name (shown on reports), scanner thread count, and request timeout are editable from the Settings page without touching
.env.
All settings live in .env (see .env.example for the full list with defaults):
| Variable | Purpose |
|---|---|
SECRET_KEY |
Flask session signing key — must be changed before any real deployment |
DATABASE_PATH |
SQLite file location, relative to the project root |
SCANNER_MAX_THREADS |
Concurrent scanner modules per scan (also editable in-app) |
SCANNER_REQUEST_TIMEOUT_SECONDS |
Per-request HTTP timeout for all scanner modules |
SCANNER_VERIFY_SSL |
Whether outbound scan requests verify TLS certs |
DEFAULT_ADMIN_USERNAME / DEFAULT_ADMIN_PASSWORD |
Seeded admin account (first run only) |
routes/reports.py's ownership lookup for report downloads iterates a user's scans/reports rather than a direct indexed query — fine at typical scale, but amodels.get_report_by_id()with an ownership JOIN would be more efficient for large deployments.- The reflection and SQL-error-detection modules are intentionally conservative heuristics (single benign test inputs, no payload chaining) — they flag indicators worth manual review, not confirmed exploitable vulnerabilities.
- No rate-limiting/throttling is currently applied to outbound scan requests beyond
SCANNER_MAX_THREADS— add a per-host delay if scanning targets with aggressive WAFs. - No built-in scheduling (recurring/cron scans) — scans are triggered manually per project.
- Screenshots: (add screenshots of the dashboard, scan results, and PDF report here before publishing)
Provided as an educational/portfolio capstone project. Use, modify, and extend freely for authorized security testing and learning purposes.