Skip to content

aingram702/phishguard

Repository files navigation

🎣 PhishGuard

AI-Powered Phishing Simulation & Security Awareness Training Platform

Python Flask Claude License Security

KnowBe4-style phishing simulation at a fraction of the cost — with AI-personalized emails and adaptive training powered by Claude.

Features · Architecture · Quick Start · Configuration · Security · Deployment


🧠 What Is PhishGuard?

PhishGuard is a self-hosted security awareness training platform that lets IT teams and security professionals:

  1. Simulate real-world phishing attacks against their own employees — using AI-generated, highly personalized emails across 7 attack scenarios
  2. Track every interaction — opens, clicks, credential submissions, and phishing reports — in real time
  3. Automatically deliver adaptive training to anyone who falls for the simulation, with a personalized debrief and quiz generated by Claude based on the specific email they received
  4. Export campaign results to Excel for compliance reporting and risk analysis

This is the kind of platform enterprise companies pay thousands of dollars per year for. PhishGuard gives you the same capability, self-hosted, for the cost of your API usage.


✨ Features

🎯 Campaign Management

  • Launch phishing campaigns targeting individual employees or entire departments
  • Select from 7 built-in attack scenarios spanning easy → medium → hard difficulty
  • AI personalizes every email based on the recipient's name, job title, department, and company
  • Bulk-import targets from CSV with validation

🤖 AI-Powered Email Generation

Every phishing email is uniquely generated by Claude Sonnet for the specific recipient. Difficulty levels are tuned to realistic detection rates:

Difficulty Characteristics Expected Click Rate
Easy Typos, generic greetings, obvious domain spoofs 30–40%
Medium Subtle domain variants, minor inconsistencies 50–60%
Hard Polished, targeted, executive-style — minimal red flags 70%+

📊 Real-Time Tracking

Four distinct tracking events per email:

  • 📧 Sent — baseline
  • 👁 Opened — 1×1 invisible tracking pixel
  • ⚠️ Clicked — unique HMAC-signed tracking link
  • 🚨 Credentials Submitted — simulated login page (credentials are immediately discarded — never stored)
  • ✅ Reported — footer "Report Phishing" link rewards correct behavior

🎓 Adaptive Training

When an employee clicks, they are immediately redirected to a personalized training module generated by Claude:

  • References the exact red flags from the specific email they received
  • Friendly, non-shaming tone to encourage engagement
  • 5-question quiz with per-question explanations
  • Completion tracked and exported in reports

📈 Reporting & Export

  • Dashboard with 30-day rolling stats (click rate, report rate, credential submissions)
  • Per-campaign detail view with individual employee statuses
  • One-click Excel export for compliance documentation

🔐 Security-First Architecture

This platform handles sensitive employee data and simulates attacks — security is not optional. See the Security section for the full audit summary.


🗺 Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                           PhishGuard Platform                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────────────┐      ┌─────────────────────────────────────────┐ │
│  │  Admin Dashboard  │ ──► │           Campaign Manager              │ │
│  │   (Flask + Auth)  │     │  (target selection, scenario, launch)   │ │
│  └──────────────────┘     └────────────────┬────────────────────────┘ │
│                                             │                           │
│                                             ▼                           │
│                              ┌──────────────────────────┐              │
│                              │   AI Email Generator      │              │
│                              │   (Claude Sonnet API)     │              │
│                              │   Personalized per target │              │
│                              └─────────────┬────────────┘              │
│                                             │                           │
│                                             ▼                           │
│                              ┌──────────────────────────┐              │
│                              │         Resend            │              │
│                              │  HMAC-signed tracking    │              │
│                              │  links embedded in HTML  │              │
│                              └─────────────┬────────────┘              │
│                                             │                           │
│                                             ▼ (email delivered)        │
│                                    Target's Inbox                       │
│                                             │                           │
│                   ┌─────────────────────────┴────────────────────┐     │
│                   │              Tracking Server                   │     │
│                   │  /o/<id>  →  Open pixel (1×1 GIF)            │     │
│                   │  /c/<id>  →  Click → Fake login page         │     │
│                   │  /c/<id>/submit → Discard creds, redirect    │     │
│                   │  /r/<id>  →  Report → "Great catch!" page    │     │
│                   │                                               │     │
│                   │  All endpoints: HMAC-verified, rate-limited  │     │
│                   └──────────────────┬────────────────────────────┘     │
│                                      │                                  │
│                                      ▼                                  │
│                         ┌────────────────────────┐                     │
│                         │   AI Training Module   │                     │
│                         │   (Claude Sonnet API)  │                     │
│                         │   Personalized debrief │                     │
│                         │   + 5-question quiz    │                     │
│                         └────────────┬───────────┘                     │
│                                      │                                  │
│                                      ▼                                  │
│              ┌───────────────────────────────────────────────┐         │
│              │              SQLAlchemy ORM / SQLite           │         │
│              │   Organizations · Users · Targets · Campaigns  │         │
│              │   CampaignSends · TrainingModules              │         │
│              └───────────────────────────────────────────────┘         │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Tech Stack

Layer Technology
Web Framework Flask 3.0
Database ORM SQLAlchemy 2.0 (SQLite dev / PostgreSQL prod)
Authentication Flask-Login + Flask-Bcrypt
CSRF Protection Flask-WTF
Secure Headers Flask-Talisman (CSP, HSTS, X-Frame-Options)
Rate Limiting Flask-Limiter
AI Generation Anthropic Claude Sonnet (via anthropic SDK)
Email Delivery Resend
HTML Sanitization bleach
Data Export pandas + openpyxl
Payments Stripe (optional)
Production Server Gunicorn

📋 Attack Scenarios

Scenario Title Difficulty
it_password_reset IT Password Reset Required Easy
shared_drive Shared SharePoint File Easy
docusign_invoice DocuSign Document Pending Medium
ms365_quarantine Microsoft 365 Quarantined Messages Medium
hr_benefits HR Open Enrollment Deadline Medium
ceo_gift_card CEO Urgent Gift Card Request Hard
payroll_update Direct Deposit Information Update Hard

Each scenario has documented red flags that the post-click training module explicitly calls out, referencing the specific email the employee received.


⚡ Quick Start

Prerequisites

  • Python 3.11+
  • A Resend account with a verified sending domain
  • An Anthropic API key

1. Clone and set up

git clone https://github.com/YOUR_USERNAME/phishguard.git
cd phishguard

python3 -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate

pip install -r requirements.txt

2. Configure environment

cp .env.example .env

Open .env and fill in your values (see Configuration for details):

FLASK_SECRET_KEY=<generate with: python -c "import secrets; print(secrets.token_hex(32))">
RESEND_API_KEY=re_your_key_here
FROM_EMAIL=noreply@yourdomain.com
ANTHROPIC_API_KEY=sk-ant-your_key_here
BASE_URL=http://localhost:5000    # Use https:// in production

3. Initialize the database

flask --app app init-db

4. Run

python app.py

Open http://localhost:5000 and sign up for your first organization account.


⚙️ Configuration

All configuration is via environment variables. Copy .env.example to .env to get started.

Required

Variable Description
FLASK_SECRET_KEY Long random string for session signing. App refuses to start without this. Generate: python -c "import secrets; print(secrets.token_hex(32))"
RESEND_API_KEY Resend API key for email delivery (starts with re_)
FROM_EMAIL Verified sender address (must be from a domain you've verified in your Resend dashboard)
ANTHROPIC_API_KEY Anthropic API key for Claude email/training generation
BASE_URL Public URL of this deployment (e.g., https://phish.yourcompany.com). Must be https:// in production.

Optional

Variable Default Description
DATABASE_URL sqlite:///phishing_sim.db SQLAlchemy DB URI. Use PostgreSQL for production.
SEND_ID_HMAC_SECRET Falls back to FLASK_SECRET_KEY Separate HMAC key for signing tracking tokens. Recommended to set independently.
RATELIMIT_STORAGE_URI memory:// Rate limiter backend. Use redis://localhost:6379/0 in production for persistence across workers.
FLASK_ENV (unset) Set to production to enable HTTPS enforcement, HSTS, and startup checks.
STRIPE_SECRET_KEY (unset) Stripe key for billing features. Leave unset to disable.

Setting up Resend

  1. Sign up at resend.com and create an API key
  2. Add and verify your sending domain in the Resend dashboard
  3. Configure DNS records for your domain as shown in DNS Setup
  4. Set FROM_EMAIL to an address at your verified domain (e.g. phishguard@yourdomain.com)

🔒 Security

PhishGuard has undergone a full security audit. All identified findings have been remediated. Below is a summary — see SECURITY.md for complete details.

Remediated Findings

Severity Finding Fix
🔴 Critical CSRF on all POST endpoints Flask-WTF CSRFProtect on all authenticated routes
🔴 Critical SSTI via render_template_string Replaced with static template
🔴 Critical Stored XSS from unsanitized AI-generated HTML bleach allowlist sanitization before storage; covers phishing emails, training content, and manager summaries
🔴 Critical No rate limiting on public tracking endpoints Flask-Limiter (10–60 req/min per endpoint)
🔴 Critical Tracking lookup used raw UUID instead of full signed ID _resolve_send() and training route now look up CampaignSend by the full HMAC-signed ID
🟠 High SECRET_KEY silently None if env var unset Startup RuntimeError — app refuses to run
🟠 High Unguarded Stripe API key assignment Conditional on env var presence
🟠 High CSV upload — no type/size validation Extension check, 5 MB limit, parse error handling
🟠 High Tracking IDs guessable / no integrity check HMAC-SHA256 signed send_id tokens
🟠 High No brute-force protection on login/signup Rate limiting: 20/min · 100/hr on login; 10/hr on signup
🟡 Medium No input validation on signup Email regex, length limits, duplicate check
🟡 Medium Email addresses logged in plaintext Replaced with sha256(email)[:8] hex digest
🟡 Medium No secure HTTP headers Flask-Talisman: CSP, HSTS, X-Frame-Options
🟡 Medium Arbitrary quiz scores accepted Server-side clamping to 0–100
🟡 Medium Oversized send_id inputs not rejected early Length check (≤ 64 chars) before HMAC verification
🔵 Low datetime.utcnow() deprecated (Python 3.12+) Replaced with datetime.now(timezone.utc)
🔵 Low Bootstrap CDN without SRI hash integrity= and crossorigin= attributes added

Credential Handling

The fake login page deliberately discards all submitted credentials. No username or password is ever logged, stored, or transmitted — only the timestamp of the submission event is recorded. This is enforced both in the code comment and server-side in track_credentials_submission().

Ethical Use

This platform is designed exclusively for authorized security awareness training. Use it only against employees who have provided implied or explicit consent through their employment agreement, and only within organizations you are authorized to test. Unauthorized phishing simulation is illegal in most jurisdictions.


🚀 Deployment

Production with Gunicorn + Nginx

# Start Gunicorn (4 workers)
gunicorn -w 4 -b 127.0.0.1:8000 app:app

Nginx configuration (example):

server {
    listen 443 ssl http2;
    server_name phish.yourcompany.com;

    ssl_certificate     /etc/letsencrypt/live/phish.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/phish.yourcompany.com/privkey.pem;

    location / {
        proxy_pass         http://127.0.0.1:8000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name phish.yourcompany.com;
    return 301 https://$host$request_uri;
}

DNS Setup for Email Deliverability

For simulation emails to reach inboxes (not spam), configure these DNS records for your sending domain. Resend provides exact values for steps 2–4 in its dashboard.

Record Type Purpose
SPF TXT Authorize Resend to send on your domain's behalf
DKIM TXT Cryptographic sender authentication
DMARC TXT Policy for failed SPF/DKIM: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com

Database

For production, replace SQLite with PostgreSQL:

DATABASE_URL=postgresql://user:password@localhost:5432/phishguard

Redis (Rate Limiting)

For multi-worker deployments, use Redis to share rate limit state across Gunicorn workers:

RATELIMIT_STORAGE_URI=redis://localhost:6379/0

📁 Project Structure

phishguard/
├── app.py                  # Main Flask application, all routes
├── models.py               # SQLAlchemy ORM models
├── ai_generators.py        # Claude API — email & training generation
├── email_engine.py         # Resend delivery + HMAC tracking IDs
├── requirements.txt        # All Python dependencies
├── .env.example            # Environment variable template
├── .gitignore
│
└── templates/
    ├── base.html           # Shared layout (navbar, flash messages)
    ├── dashboard.html      # 30-day stats overview
    ├── fake_login.html     # Simulated credential-harvesting page
    ├── training.html       # Post-click AI training + quiz
    └── report_success.html # "Great Catch!" confirmation page

📊 Data Models

Organization ──< User          (multi-admin support)
Organization ──< Target        (employees to be phished)
Organization ──< Campaign      (a phishing campaign)
Campaign     ──< CampaignSend  (one email per target)
CampaignSend ──< TrainingModule (one training module per click)

Each CampaignSend records the full lifecycle: sent → opened → clicked → credentials submitted / reported → training started → training completed + quiz score.


🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Follow the existing code style
  4. Ensure no new datetime.utcnow() or Query.get() calls (use the patterns already in the codebase)
  5. Do not introduce render_template_string or innerHTML with string concatenation
  6. Open a pull request with a clear description

Running Tests

# Install dev dependencies
pip install pytest pytest-flask

# Run tests
pytest

📄 License

MIT License — see LICENSE for details.


⚠️ Disclaimer

This software is provided for authorized security awareness training only. The authors are not responsible for misuse. Always obtain written authorization before conducting phishing simulations against any organization or individuals. Review your local laws and regulations before deployment.


Built with ❤️ for security teams who want enterprise-grade awareness training without enterprise-grade pricing.

Report a Bug · Request a Feature · Security Disclosure

About

KnowBe4 for SMBs at 1/10th the price, with AI-personalized training. Work in Progress...

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors