GitHub RadarBlue team tool
"No Phishing" provides robust, real-time protection against phishing threats, ensuring safe browsing and enhanced internet security. Primary language: Jupyter Notebook. 16 stars.
Project links:Open GitHub projectBack to radar
<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 --> <a name="readme-top"></a>
[![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![GPL-2.0 license][license-shield]][license-url] [![LinkedIn][linkedin-shield]][linkedin-url]
<!-- PROJECT LOGO --> <br /> <div align="center"> <a href="https://github.com/cprite/phishing-detection-ext"> <img src="images/logo.png" alt="Logo" width="200" height="200"> </a>
<p align="center"> <br /> <br /> <br /> <a href="https://github.com/cprite/phishing-detection-ext/issues">Report Bug</a> · <a href="https://github.com/cprite/phishing-detection-ext/issues">Request Feature</a> </p> </div>
<!-- TABLE OF CONTENTS --> <details> <summary>Table of Contents</summary> <ol> <li> <a href="#about-the-project">About The Project</a> <ul> <li><a href="#disclaimer">[!] Disclaimer</a></li> <li><a href="#built-with">Built With</a></li> </ul> </li> <li> <a href="#getting-started">Getting Started</a> <ul> <li><a href="#retrain-the-model">Retrain the Model</a></li> </ul> </li> <li><a href="#how-it-works">How It Works</a></li> <li><a href="#model-performance">Model Performance</a></li> <li><a href="#contributing">Contributing</a></li> </ol> </details>
<!-- ABOUT THE PROJECT -->
No Phishing is a self-contained Chrome extension that detects phishing URLs in real time. The classifier is a K-Nearest-Neighbours model implemented in pure JavaScript — no companion server, no ONNX, no WebAssembly, no data sent anywhere. It achieves 89.4% test accuracy on 11 browser-computable features, and because KNN is instance-based it learns in the browser: your corrections become new data points that immediately affect future predictions.
This extension is intended as a supplementary tool for online safety. While it demonstrates high accuracy, it is not infallible. As the developer, I am not a certified cybersecurity professional, and the extension could make errors. Users are advised to exercise caution and judgment. By using "No Phishing," you acknowledge and accept responsibility for your online safety.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- GETTING STARTED -->
No Python, no server, no setup. Just load the extension:
git clone https://github.com/cprite/phishing-detection-ext.gitchrome://extensions/.phishing-detection-ext directory.The seed dataset (saved_models/seed_model.json — scaled training points, labels and frozen scaler parameters) is committed and ready to use. To regenerate it:
Web page phishing detection dataset Save it as raw_data/dataset_phishing.csv.
pip install -r requirements.txt
python export_model.pyThis overwrites saved_models/seed_model.json and prints the KNN accuracy.
The original 22-feature KNN baseline and browser feature-selection rationale are documented in cyberguard_phishing_detection.ipynb.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- HOW IT WORKS -->
Everything runs locally in your browser. No server, no network calls, no data leaves your device.
Content script (extension/content.js) — injected into every http/https page at document_idle. Sends the current URL and hyperlink count (document.querySelectorAll('a').length) to the service worker.
Service worker (extension/background.js) — receives the page report, extracts 11 features via extension/features.js, scales them with the frozen scaler and classifies with extension/knn.js over the merged seed + feedback dataset (extension/storage.js). If phishing, it redirects the tab to the built-in warning page.
KNN classifier (extension/knn.js) — a pure-JS port of scikit-learn's KNeighborsClassifier(n_neighbors=3, metric="manhattan") plus MinMaxScaler.transform. Classification is a majority vote of the 3 nearest seed points. Verified to match scikit-learn's predictions on 99.95% of the test set.
Seed dataset (saved_models/seed_model.json) — the scaled training points, labels and frozen scaler parameters, exported by export_model.py. ~7 700 points from the Hannousse & Yahiouche dataset (≈9 600 samples after cleaning).
Trusted sites — clicking Proceed on a warning adds that page's hostname to a local trusted list (chrome.storage.local). Pages on a trusted hostname are never blocked, but in the open-source build they are still scored silently in the background: a trusted host is treated as ground truth, so if the model ever flags one as phishing that verdict is fed back as a legitimate point automatically (no warning, no prompt). Manage (and remove) trusted sites from the extension popup. The list never leaves your device.
Lookalike-domain detector (extension/lookalike.js) — a deterministic rule that runs alongside the KNN, which has a blind spot on short, clean-looking brand-impersonation phishing. It checks the hostname against a list of ~50 commonly-impersonated brands with four detectors:
| Detector | Example | Confidence | Action | |---|---|---|---| | Subdomain / hyphen brand injection | apple.account-secure.com, secure-paypal.example.com, brand-bearing *.vercel.app / *.now.sh | 95% | force PHISHING | | Homoglyph swap (0↔o, 1↔l/i, rn↔m, vv↔w) | paypa1.com, m1crosoft.com, rnicrosoft.com | 90% | force PHISHING | | Typosquat — Damerau-Levenshtein 1 edit | microsfot.com, paypai.com | 90% | force PHISHING | | Typosquat — 2 edits | paypa11.com | 80% | suspect only (no block) | | TLD spoofing — brand on non-official TLD | paypal.net, netflix.org | 80% | suspect only (no block) |
A forced hit overrides the KNN vote and shows the reason on the warning page (e.g. “Domain ‘paypa1.com’ appears to be a homoglyph of ‘paypal.com’”). A suspect match (could be legitimate) never blocks on its own — it is recorded to chrome.storage.local (lookalike_suspects) and its reason rides along only if the page is blocked for another reason.
False positives are guarded several ways: a whitelist of genuine registrable domains (and common ccTLD variants) short-circuits the real brand sites and all their subdomains; brand tokens match on label/hyphen boundaries, not raw substrings (so startups never matches ups, governance never matches gov); and fuzzy matching only runs for brands ≥ 5 chars of comparable length. On a 25-URL live OpenPhish sample plus a 45-case labelled test set the detector reached 100% recall with zero false positives — but it only knows the brands in its list, and registrable-domain parsing uses a small built-in suffix list rather than the full Public Suffix List.
The 11 features — 10 lexical features derived from the URL string (length, character counts, digit ratio, suspicious-token hits) plus the page hyperlink count. WHOIS lookups, redirect-history probes, and word-length features that require a public-suffix-aware tokenizer are all omitted — they either cannot be computed client-side or cannot be reproduced in JS with exact parity to the training data. Feature formulas are verified to produce 800/800 exact-match parity with the training dataset columns.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- SELF-LEARNING -->
KNN is instance-based — it classifies by comparing against stored points — so *adding a labelled point is retraining*. There's no offline step and no model file to rebuild: corrections take effect on the very next page you visit.
Your corrections are saved as scaled feature points in chrome.storage.local (feedback_points) and merged with the seed dataset at every inference. Two triggers (open-source build only):
legitimate point (a false positive the model got wrong).legitimate point automatically and silently — the trusted list is the source of truth, so a flag there is a correction signal.phishing point (a page the model missed).Everything stays on your device. (This is disabled in the Chrome Web Store build — see Builds.)
<a name="builds"></a>
The repository is the open-source build (extension/config.js → IS_OSS_BUILD = true): the self-learning features above are included.
The Chrome Web Store build strips them. Generate it with:
python build_cws.pyThis writes dist/cws/ (load it to verify) and dist/no-phishing-cws.zip (upload it). It flips IS_OSS_BUILD = false — hiding the "Mark as phishing" button and stopping "Proceed" from adding points, so the store build never collects feedback — and leaves the Python scripts, dataset and docs out of the package.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- MODEL PERFORMANCE -->
Results on the held-out test set (20% split, stratified, random_state=42):
| Model | Features | Test Accuracy | Phishing Precision | Phishing Recall | |-------|----------|:---:|:---:|:---:| | KNN (k=3, manhattan) — previous server build | 22 (incl. WHOIS) | 92.65% | 93.98% | 90.89% | | KNN (k=3, manhattan) in JS — this build | 11 (browser-only) | 89.42% | 88.55% | 90.15% |
The browser build trades ~3 points of accuracy for two things the server build can't offer: it runs entirely client-side (no server, no ONNX, no WebAssembly), and it learns from your corrections in real time — every "Proceed" or "Mark as phis