AI-driven phishing detection
Phishing detection on 235,795 URLs, with a leakage fix, a SOC cost model and a poisoning test
Problem
Phishing is a leading initial-access vector (MITRE T1566.002). On a public benchmark it is easy to report near-perfect accuracy that means little. The questions: is the accuracy real, what threshold makes sense for a SOC that pays for both false alarms and missed phish, and how brittle are the models when an attacker corrupts the training data?
AI for Cyber Security coursework (CSEC3004): building and critically evaluating phishing classifiers on the public PhiUSIIL Phishing URL dataset. The whole analysis is in a Jupyter notebook in the public repo, with its outputs saved.
What I did
I engineered URL and page features (the dataset includes page-content signals such as HasSocialNet and HasCopyrightInfo, not just the URL). A first run gave a suspicious 1.0 accuracy, which I traced to two leaky “oracle” features, URLSimilarityIndex and LineOfCode, and dropped. I then tuned and compared six models on a stratified 80/20 split: Logistic Regression, Random Forest, XGBoost, LightGBM, CatBoost and an MLP.
Catching the leak
The first models scored a perfect 1.0, which is a warning sign rather than a result. Correlation analysis showed URLSimilarityIndex (correlation 0.86 with the label) and LineOfCode acting as oracles for the answer. I dropped both, and split the data before scaling so nothing from the test set leaked into training.
Model comparison (clean test set)
Accuracy / false-positive rate / false-negative rate on the 20% held-out split, from the notebook’s results table:
- Logistic Regression 0.9991 / 0.0011 / 0.0007
- Random Forest 0.9996 / 0.0005 / 0.0003
- XGBoost 0.9999 / 0.0002 / 0.0001
- LightGBM 0.9999 / 0.0002 / 0.0000
- CatBoost 0.9998 / 0.0004 / 0.0001
- MLP 0.9997 / 0.0003 / 0.0002
SOC cost model
I modelled a SOC that sees 1,000,000 URLs a day, 0.5% of them phishing, where a false positive costs $15 of analyst triage and a missed phish costs $5,000. Sweeping the threshold gave an optimum of 0.61 and a minimum expected cost of about $4,072 a day.
Poisoning test
I flipped 1, 5, 10, 15 and 20% of the training labels and re-measured accuracy on clean test data (Random Forest and XGBoost). From the notebook’s plot: Random Forest stayed at about 0.9995 at every rate, while XGBoost fell steadily, to about 0.997 at 20%. Bagging averages out the noise; boosting keeps fitting it.
Evidence
- Best test accuracy
- 0.9999
- XGBoost and LightGBM · stratified 20% test split
- Cost-optimal threshold
- 0.61
- $15 per false alarm vs $5,000 per missed phish
- URLs in dataset
- 235,795
- PhiUSIIL (43% phishing)
- Models compared
- 6
- linear · bagging · boosting ×3 · MLP
Stack and tools
Result
An evaluation that treats ML as a security control rather than a leaderboard: it rejects a too-good result, chooses a threshold from what errors cost a SOC, and shows which model family survives poisoned training data.
Limitations
Every model scored a ROC-AUC of 1.0000, even after the leakage fix: PhiUSIIL is close to separable, so these scores overstate real-world performance. The 0.5% phishing rate and the dollar costs are modelling assumptions, not measured figures. The poisoning numbers are read from a plot, and the poisoning test covered two models only.