Why
Every corporate cybersecurity training I sat through taught me one thing: how to click "I understand" as fast as possible. None taught me to actually spot a phishing email.
So I built CyberEduc, a free open-source anti-phishing training platform. The goal was simple: train pattern recognition through short lessons and hands-on exercises with realistic phishing scenarios.
What's inside
7 short lessons on homograph attacks, URL shorteners, email spoofing, social engineering, email authentication (SPF/DKIM/DMARC), spear phishing, and incident response. Each ends with a quiz.
A Red Flag Trainer where you face real phishing emails side by side with legitimate ones. Click every suspicious token before the timer runs out. Three difficulty levels.
Progression system: XP, levels, badges. From Phish Spotter to Human Firewall.
Auth: email/password with confirmation and password reset.
Privacy first: no tracking, no analytics, no ads. Data encrypted at rest, EU-hosted.
Tech stack
Nothing exotic, but every choice was deliberate.
Frontend : vanilla HTML/CSS/JS, no framework
I hesitated on this a lot. React would have been faster to build. But CyberEduc is a security awareness site — hiding the frontend behind a bundler felt wrong. Anyone should be able to view-source and read what's happening. Vanilla JS made that transparent.
Fonts: Inter (body), Instrument Serif (italic accents), JetBrains Mono (code/UI labels). The editorial look was inspired by publications like The Verge Redesign and modern SaaS landing pages.
Backend: FastAPI (Python)
Type hints via Pydantic, async by default, docs auto-generated at /docs. JWT auth issued server-side. REST API under /api. Total code: ~600 lines across auth, lessons, badges, and redflag routes.
Data: Supabase
PostgreSQL with Row Level Security for user data. Supabase Auth for the confirm-email and password-reset flows. Content (lessons + scenarios) lives as JSON files in data/, not in the database , makes contributions dead simple (PR a JSON file, done).
Email: Brevo SMTP
Custom editorial HTML templates for confirmation and reset emails. Matches the site's black + green accent aesthetic.
Deploy: Nginx on a Contabo VPS
Static frontend + reverse proxy to FastAPI. Let's Encrypt for SSL. Systemd for the API service.
Design decisions I hesitated on
JSON content vs a CMS. A CMS would have been more powerful but overkill for 7 lessons. JSON files in git means version-controlled content, dead-simple PRs, no admin panel to secure, no runtime dependency. Trade-off: no non-technical editors. Fine for now.
No analytics. Zero tracking, zero heatmaps, zero funnel analysis. On principle, but also because I don't want to be the "anti-phishing site that fingerprints its users". If I need engagement data later, I'll add opt-in Plausible.
Vanilla JS. Already covered. Wins on transparency and load time. Loses on velocity for complex features. If I ever need real interactivity beyond what's there, I might rewrite specific pages in Svelte. But not yet.
Editorial design. Most cybersecurity products look like enterprise SaaS from 2015: gradients, stock photos of hackers in hoodies, "protect your business" copy. I went the opposite direction — magazine-like layout, Instrument Serif italic accents, black and one accent green. Wanted the site to feel like a place where you learn, not where you buy compliance.
Lessons learned building this
Build the boring parts first. I spent the first week on the Red Flag Trainer because it was fun. Then had to backtrack and build auth, sessions, JWT handling, email confirmation, password reset. If I could redo it, I'd start with the auth flow — it's what unlocks everything else.
Emails are hard. Custom HTML emails that render correctly across Gmail web, Gmail iOS, Apple Mail, Outlook, and Thunderbird required table-based layouts, inline styles, and a lot of testing. Google Fonts import works in some clients and not others. Fallback stacks matter.
Supabase RLS is powerful but tricky. Row Level Security is elegant when you get it, but the debug cycle is painful. Every "this insert fails silently" required checking policies twice. Worth it for the security guarantees.
Free tiers stack. The entire production stack is on free tiers: Supabase (up to 500MB), Brevo (300 emails/day), Contabo VPS (~4€/month, not free but close). Total cost per month: less than a coffee. Solo indie budget.
What's next
More lessons: OAuth phishing, MFA bypass, deepfake voice phishing
i18n (French, Spanish)
Team mode with aggregated stats for orgs training their employees
Better mobile UX for the Red Flag Trainer (tokens are small on phone screens)
Contribute
Everything is MIT licensed. Contributions welcome:
- New lessons: drop a JSON file in data/lessons/, follow the schema in CONTRIBUTING.md
- New Red Flag scenarios: same, in data/redflag/
- Bug reports and feature ideas: open an issue
Happy to answer questions in the comments about the stack, the design choices, or the content approach.
Top comments (1)
One thing I'd love feedback on from folks here:
The Red Flag Trainer content is authored as JSON in data/redflag/{beginner,intermediate,advanced}.json. Each scenario has a real email and a fake email with a list of "red flag" substrings that the trainer tokenizes as clickable targets.
The current scenarios are US/EU-centric (Amazon, PayPal, banks). If you've seen creative phishing attempts specific to your region, industry, or platform , I'd love a PR (or even just a description in a comment). The schema is documented in CONTRIBUTING.md.
Also curious: what phishing patterns do you think are most underrated / underestimated in awareness training today?