fraudurl: fast, offline
phishing URL detector
A free phishing URL checker for Python: check one link or a whole CSV of URLs for phishing (look-alike login, payment and account pages). Every row gets a verdict (FRAUD, REVIEW or LEGITIMATE), a calibrated probability and up to three plain-English reasons. One Python file, no dependencies, and it never visits the websites.
pip install fraudurlCheck a list of URLs for phishing in one command
fraudurl is a command-line phishing URL checker written in Python. Point it at any CSV or text file of links. The URL column is found automatically, and the same file comes back with the verdict columns added. Step-by-step guide.
python fraudurl_standalone.py urls.csv # writes urls.fraudurl.csv
python fraudurl_standalone.py --url "http://paypal.com.secure-login.test/webscr/login.php" # one URL -> JSON
python fraudurl_standalone.py urls.csv --enrich-review # add DNS + domain-age lookups for unsure URLs
Why fraudurl
Never visits the website
It judges the URL itself: 83 clues such as a brand in the wrong place, login or payment words, free-hosting addresses, risky domain endings and random-looking names.
One file, no dependencies
The whole tool, models included, is a single 450 KB Python file for Python 3.9+. It runs on Windows, macOS and Linux, and is tested on each.
Explains every verdict
The reasons are the model's own per-feature contributions, such as "brand name in the subdomain" or "uses unencrypted http://", not a separate guess.
Private by default
Offline mode sends nothing anywhere. Optional lookups ask DNS and the domain registry about the domain, never the site.
Fast at scale
About 1,000 URLs a second on one CPU core and 2,600–3,200 on four. It checked a million URLs in 6 minutes 20 seconds on a 4-core desktop, with memory flat at about 230 MB.
Says when it is unsure
Ambiguous URLs go to REVIEW for a person instead of being guessed. Your own allow and block lists always win.
How it works
1. Read the URL like a browser
Use the Public Suffix List to find the domain someone actually bought, and catch disguised IP addresses and look-alike letters.
2. Measure 83 clues
Structure, character mix, randomness, redirect tricks, brand and login words, free hosting, and the phishing history of the domain ending.
3. Score and calibrate
The URL classifier, a 400-tree gradient-boosted model, runs in plain Python. Its score is calibrated into a probability, and cut-offs turn that into a verdict.
4. Explain
Up to three clues that moved the score most are written out in plain English. Optional DNS and registration lookups refine unsure URLs.
How accurate is it?
Measured on URLs from domains the model never saw in training: held-out test splits of its three training datasets, plus one dataset (Ariyadasa 2021) never used for training at all, 2020 to 2026.
| Test data | ROC-AUC | Legitimate called FRAUD | Phishing called LEGITIMATE | Sent to REVIEW |
|---|---|---|---|---|
| PhreshPhish 2024–25 | 0.984 | 0.3% | 2.6% | 18% |
| 2026 collection | 0.975 | 1.8% | 1.6% | 24% |
| Ariyadasa 2021 (fully external) | 0.958 | 1.8% | 2.1% | 33% |
| Hannousse 2020 | 0.907 | 1.3% | 4.9% | 45% |
Two caveats. The probabilities assume about half of your URLs are phishing;
when phishing is rare, many FRAUD verdicts will be false alarms (at 1% prevalence, 26–73% of FRAUD verdicts
were real phishing, depending on the test set), so pass --base-rate. And the final set-up was
chosen partly by looking at these results, so the numbers are slightly optimistic.
It is a fast first-line filter for triage, not a replacement for a full phishing-defence stack. The limitations are listed openly in the model card and the engineering report.
Frequently asked questions
How do I check if a link is phishing?
Run python fraudurl_standalone.py --url "https://example.com/login". It prints a verdict (FRAUD,
REVIEW or LEGITIMATE), the probability of phishing and the reasons, without opening the link.
How do I check a list of links for phishing?
Save the links in a CSV or text file and run python fraudurl_standalone.py links.csv. You get the
same file back with a verdict, probability and reasons on every row, ready to sort in Excel.
Does fraudurl detect malware or other scam links?
It is built and tested for phishing URLs: fake login, payment and account pages. It has not been measured on malware downloads or other kinds of malicious or scam URLs, so a LEGITIMATE verdict does not mean a link is safe from those. Use a malware scanner or a blocklist service for them as well.
Can I use it from my own Python code?
Yes, as a command-line tool: call it with subprocess and read one JSON object per URL
(--url or --format json). Version 1.0 has no import-level Python API.
Is fraudurl free?
Yes. It is open source under the MIT License, with no accounts, API keys or paid services.
Does it work offline?
Yes. The default mode never touches the network. The optional --enrich-review mode looks up DNS
and domain registration data, but still never visits the website itself.
Is it safe to check suspicious links with fraudurl?
Yes. It never opens, downloads or submits anything at the URLs it checks. It reads the address text only, so checking a phishing link does not expose you to the page. In the default offline mode nothing is sent anywhere. With the optional lookups, the host name goes to Cloudflare's DNS service, so the domain's own DNS servers can see that the name was looked up (from Cloudflare, not from your computer).
How is it different from Google Safe Browsing or VirusTotal?
Google Safe Browsing and VirusTotal are online services: they check a URL against threat lists and, for VirusTotal, the verdicts of many security vendors, backed by far more data than any local model. fraudurl runs entirely on your machine, needs no account, checks a million-URL CSV in minutes and explains each verdict. Because it judges the address itself instead of looking it up, it can also give a verdict on a URL that is not on any list yet. It was tested on domains it never saw in training, but it has not been compared with those services. Use them together.
Which Python versions and systems are supported?
Python 3.9 to 3.14 on Windows, macOS and Linux. CI tests every change on all six Python versions on Windows and Linux, and on 3.10 to 3.14 on macOS.