What I Built
The Breadcrumb Engine is a Python tool that takes a list of IP addresses and plots them on an interactive dark-mode map, enriched with real-time threat intelligence from VirusTotal. Each IP is colour-coded by risk level and the full dataset is exportable as CSV.
🟢 Green → 0–4% (Clean)
🟠Orange → 5–14% (Suspicious)
🔴 Red → 15%+ (Malicious)
The Stack
- Streamlit — web UI with zero frontend code
- Folium — interactive map rendering on a CartoDB dark basemap
- VirusTotal API — aggregates 90+ security vendor votes per IP
- ipinfo.io — HTTPS geolocation
- pandas — data handling and CSV export
What I Learned
1. Never hardcode API keys
This seems obvious but it's easy to slip up when prototyping. The fix is simple — use environment variables:
VT_API_KEY = os.environ.get("VT_API_KEY")
And on Mac, make it permanent:
echo 'export VT_API_KEY="your_key_here"' >> ~/.zshrc
source ~/.zshrc
2. HTTP geolocation is a MITM risk
The original version used http://ip-api.com — plain HTTP. On a cloud server, that traffic is unencrypted and could be intercepted and spoofed. I switched to https://ipinfo.io which supports HTTPS on the free tier.
3. Rate limiting matters
VirusTotal's free tier allows 500 requests/day. With a thread pool and a 1.4s delay between requests, the app stays well within limits without blocking the UI.
RATE_LIMIT_DELAY = 1.4
MAX_WORKERS = 2
4. Input validation before hitting any API
Users can paste anything into a text box. A simple regex check protects all downstream API calls:
def is_valid_ip(ip: str) -> bool:
pattern = r"^(\d{1,3}\.){3}\d{1,3}$"
if not re.match(pattern, ip):
return False
return all(0 <= int(octet) <= 255 for octet in ip.split("."))
5. VirusTotal scores differently to AbuseIPDB
AbuseIPDB gives a single confidence score out of 100. VirusTotal gives votes from 90+ vendors. To convert to a 0–100 scale I calculate the percentage of vendors that flagged it:
stats = resp.json()["data"]["attributes"]["last_analysis_stats"]
malicious = stats.get("malicious", 0)
suspicious = stats.get("suspicious", 0)
total = sum(stats.values())
return round(((malicious + suspicious) / total) * 100)
Try It Yourself
The full source code is on GitHub: [YOUR GITHUB LINK]
Clone it, set your VirusTotal API key and run:
git clone git clone https://github.com/shynsec/breadcrumb-engine.git
cd breadcrumb-engine
pip install -r requirements.txt
export VT_API_KEY="your_key_here"
streamlit run app.py
Feedback and contributions welcome. What features would you add next?


Top comments (0)