Phishing URL Detector (XGBoost)
Live demo: https://phishing-website-detector-k5mb3cndcjkvrkcfaypexz.streamlit.app/ Source code: https://github.com/6305-0026-1762/phishing-website-detector
MSc Dissertation model: A Deep Learning Framework for Phishing Website Detection Using URL and HTML Features. Student: Sushma Singahalli Parashuramappa (250638286). Supervisor: Bo Wei.
XGBoost classifier trained on a combined dataset of 21,260 URLs from two independent
sources (Hannousse & Yahiouche + an independent 835k-URL corpus, deduplicated across
sources). Uses 37 lexical features extracted from the URL string alone (no HTML
content or live page data) โ see feature_names.joblib for the exact feature order
and the companion url_features.py extractor.
Test set performance
- Accuracy: 0.9104
- F1-score: 0.9100
- ROC-AUC: 0.9657
- False positive rate: 8.5%
Files
xgboost.joblib- the trained model.scaler.joblib-StandardScalerfitted on the training split; apply before prediction.feature_names.joblib- exact feature order the model expects.
Usage
from huggingface_hub import hf_hub_download
import joblib, numpy as np
model = joblib.load(hf_hub_download("Twinkytuffy/phishing-url-detector-model", "xgboost.joblib"))
scaler = joblib.load(hf_hub_download("Twinkytuffy/phishing-url-detector-model", "scaler.joblib"))
feature_names = joblib.load(hf_hub_download("Twinkytuffy/phishing-url-detector-model", "feature_names.joblib"))
# feats = extract_url_features(url) # see url_features.py
# x = scaler.transform([[feats[n] for n in feature_names]])
# proba_phishing = model.predict_proba(x)[0, 1]
Known limitation
The training data's legitimate class skews toward short, bare domains rather than
www.-prefixed global brands, so some well-known root-domain-only URLs can land
close to the 50% decision boundary. This is a dataset-composition limitation of the
lexical-only feature set, not a bug โ see the dissertation's overfitting/underfitting
analysis (Section 5.6) for a full discussion.