Deployable demo for the paper: CYBERX: A Hybrid Multi-Modal Framework for Phishing Detection Using BERT, URL Analysis, and HTML Structural Features Aditya Singh · Daksh Sharma · Harshvardhan Choudhary · Galgotias University, 2025
A Flask web app that runs the CYBERX pipeline end-to-end: paste an email + a suspicious URL and get a phishing verdict in under 200 ms, with per-branch risk scores and the top contributing features.
┌──────────────────────────────────────────────────────────────┐
│ CYBERX — multi-modal phishing detection │
├──────────────────────────────────────────────────────────────┤
│ │
│ email ─┐ │
│ ├── BERT [CLS] (768-d) ──┐ │
│ URL ───┼── 30+ URL features ────┼──► fusion ──► verdict │
│ │ │ │
│ HTML ──┴── DOM parser ──────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
- A live web demo with a polished UI for showing reviewers / committee members
- Per-branch risk breakdown — see exactly why CYBERX flagged something
- Top contributing features with importance scores (explainable predictions)
- Paper benchmark dashboard showing all 8 models from Table I
- One-command Docker deploy (
docker build && docker run) - Reproducible training pipeline (the original Colab notebook ships in
scripts/)
# 1. Install
pip install -r requirements.txt
# 2. Train the fusion model (~10 seconds on CPU)
python scripts/train_fusion.py
# 3. Launch the demo
python app/server.py
# → open http://localhost:5000That's it. The model file (models/cyberx_fusion.joblib) is created on first training run and is git-ignorable.
docker build -t cyberx .
docker run -p 5000:5000 cyberx
# → open http://localhost:5000Any platform that supports a Python web service works. Set the start command to:
python app/server.py
The training step happens at Docker build time, so the deployed container starts in <2 s.
cyberx_project/
├── app/
│ ├── server.py # Flask backend + JSON API
│ ├── templates/index.html # dashboard UI
│ └── static/{style.css,app.js}
├── features/
│ ├── url_features.py # 35 lexical / host / transport / redirection features
│ ├── html_features.py # 24 DOM structural features (BeautifulSoup)
│ └── email_features.py # email-text features (+ optional BERT mode)
├── models/
│ ├── cyberx_fusion.py # fusion classifier with explainable predictions
│ ├── cyberx_fusion.joblib # trained Random Forest (created by training script)
│ └── deployment_metrics.json
├── scripts/
│ ├── train_fusion.py # train the deployable model
│ └── cyberx_train_v2.ipynb # original Colab — reproduces the paper numbers
├── docs/
│ └── DEMO_GUIDE.md # what to show reviewers
├── Dockerfile
├── requirements.txt
└── README.md
Fine-tuned bert-base-uncased returns a 768-dim CLS embedding. In the Colab pipeline (scripts/cyberx_train_v2.ipynb) this is trained for 3 epochs on the public zefang-liu/phishing-email-dataset. For the deployable demo the email branch uses lightweight handcrafted features (urgency words, credential prompts, generic greetings, "verify-your-account" combinations) so it runs on CPU in milliseconds. Swap in the BERT checkpoint by setting BertEmailEncoder(checkpoint_path=...) in features/email_features.py.
35 numeric features grouped into four families from Section III-C of the paper:
- Lexical — length, dots, slashes,
@,-, Shannon entropy, digit ratio - Host-based — IP-as-host detection, subdomain count, brand keywords, suspicious TLDs
- Transport — HTTPS, nonstandard ports
- Redirection — URL shorteners, redirect parameters
BeautifulSoup parses the landing page and computes 24 structural features:
- hidden iframes, external script sources
- forms with cross-domain
actions - password fields, hidden inputs
- obfuscated JavaScript (
eval,unescape,fromCharCode, hex strings,atob) - meta-refresh redirects, external/internal link ratio, external favicon
If the page can't be reached the branch is gracefully skipped — the model falls back to email + URL only.
The three vectors are L2-normalised per branch and concatenated (78 features total). A Random Forest with 400 trees produces P(phishing). The full feed-forward fusion network from Algorithm 1 of the paper is implemented in scripts/cyberx_train_v2.ipynb for the published results.
The Random Forest trained by scripts/train_fusion.py is the deployment model — trained on bundled examples for fast first-run. The numbers reported in the paper come from scripts/cyberx_train_v2.ipynb, which:
- Downloads the UCI Phishing Websites dataset (11,055 URLs, 30 features) via
ucimlrepo - Downloads the
zefang-liu/phishing-email-datasetfrom Hugging Face (~5,000 emails sampled) - Trains all 7 baselines + the BERT branch on a free Colab T4 GPU
- Trains the fusion network and saves all metrics + figures
Open the notebook in Google Colab → Runtime → Change runtime to T4 GPU → Run all. ~30-45 minutes end-to-end. The output zip matches the figures in the paper.
| Endpoint | Method | Purpose |
|---|---|---|
/ |
GET | Dashboard UI |
/api/health |
GET | Liveness + capability check |
/api/metrics |
GET | Paper + deployment metrics (for the dashboard table) |
/api/scan |
POST | Run CYBERX on {email_text, url, html?, fetch_landing_page?} |
/api/example/<kind> |
GET | Pre-canned demo inputs (phishing, legitimate, ip_phish, shortener) |
curl -X POST http://localhost:5000/api/scan \
-H "Content-Type: application/json" \
-d '{
"email_text": "URGENT: Verify your password now or your account will be suspended!",
"url": "http://paypal-secure-update.tk/login.php",
"fetch_landing_page": false
}'Response:
{
"verdict": "PHISHING",
"probability": 0.9625,
"confidence": 0.9625,
"model": "CYBERX (Random Forest fusion)",
"branches": {
"email": { "risk_score": 1.0, "signals": { "urgency_words": 5, ... } },
"url": { "risk_score": 0.45, "signals": { "suspicious_tld": true, ... } },
"html": { "available": false, "risk_score": 0.0 }
},
"top_features": [...],
"timing_ms": 28.4,
"fetched_landing_page": false
}- Open
http://localhost:5000 - Click the "phishing email" example button → click analyze
→ verdict is
PHISHINGat ≥95% probability, all three branches show their signals - Click "legitimate email" → click analyze
→ verdict is
LEGITIMATEat <1% probability - Click "IP-host attack" → analyze → URL branch lights up the IP-as-host and no-https signals
- Click "URL shortener" → analyze → URL branch flags shortener; combined with reward language pushes the verdict
- Scroll down to the Paper results table — CYBERX is the highlighted row at 97.60% accuracy
The full demo guide is in docs/DEMO_GUIDE.md.
If you use this code, please cite the paper:
@inproceedings{singh2025cyberx,
title = {CYBERX: A Hybrid Multi-Modal Framework for Phishing Detection
Using BERT, URL Analysis, and HTML Structural Features},
author = {Singh, Aditya and Sharma, Daksh and Choudhary, Harshvardhan},
year = {2025},
school = {Galgotias University, Department of CSE}
}