Threat Intel for $0: A Passive Dashboard on Free Public Feeds
Most sites that talk about threat intel eventually ask you for a credit card. This one doesn't. The dashboard I built runs on zero API keys, costs nothing to host, and surfaces the same underlying data that powers a lot of expensive commercial platforms — because those platforms are often just wrapping the same free public feeds.
The tool is live at passive-intel.vercel.app. Source at github.com/noisyloop/passive-intel. Fork it, deploy it, use it. Five minutes, no secrets to manage.
This post covers what it pulls, why free feeds are underrated, and how to turn the data into actual blocks on infrastructure you control.
What It Pulls
Three panels. All read-only. Nothing here touches a target — every data point is cached public intelligence queried server-side.
- CISA KEV — the Known Exploited Vulnerabilities catalog. Newest first, filterable by vendor, product, or CVE ID. Expand any entry for the description and a live CVSS base score from NVD. Ransomware-linked entries are flagged.
- URLhaus (online feed) — malware URLs actively serving payloads right now, not historical. Filterable by host, threat type, or tag.
- Feodo Tracker — active botnet C2 IPs with malware family and country. Emotet, QakBot, AsyncRAT. The same feed many commercial platforms resell.
The Free Feeds Doing the Work
- CISA KEV — confirmed in-the-wild exploitation. Free JSON, no auth, updated frequently.
- URLhaus (abuse.ch) — community-sourced malware URL feed, online-only subset. Free CSV, no auth.
- Feodo Tracker (abuse.ch) — active botnet C2 IPs. Free JSON, no auth.
- NVD — CVSS base scores from NIST. Free REST API, no auth at reasonable rate.
The reason these feeds are good is that they're maintained by people who care about the data, not about upselling you. abuse.ch in particular runs URLhaus, Feodo Tracker, MalwareBazaar, and ThreatFox — all free, all community-driven, all legitimate primary sources.
On the no-API-key design
The absence of credentials here is intentional architecture, not an oversight. Every feed in this stack is open by design. The moment you add a credentialed API, the key has to live somewhere — and that somewhere is usually a server-side environment variable, not a client-side JS file and definitely not a public repo.
The zero-cost, zero-secret constraint forces cleaner architecture. It also means anyone can fork this and run it without asking their org for budget approval or managing secrets rotation.
The Security Posture of the App Itself
The feeds contain attacker-influenced data. Live malware URLs. Active C2 IPs. Threat actor tags. The client is paranoid about rendering any of it.
Every dynamic value goes through textContent, never innerHTML. Malware URLs display as inert plain text with no <a href>. A poisoned feed entry with a script tag renders as visible text, not code. The CSP is a second independent layer: default-src 'none', script-src 'self', connect-src 'self'.
The API functions reject scanner traffic before any handler logic runs. Missing or known-bad User-Agent strings get a 403. Rate limiting is per-IP per-endpoint. Unknown paths return a clean 404 from a dedicated handler — nothing useful leaks about routing.
Actually Blocking the Threats
The dashboard also exposes /api/blocklist.txt — one Feodo C2 IP per line, pulled from the live feed and cached at the edge. Point a cron job at it and you're blocking confirmed active C2 infrastructure on an hourly refresh. Or pull directly from Feodo's recommended list. Either works.
nginx
#!/bin/bash
# /etc/cron.hourly/update-feodo-blocklist
curl -sf https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt \
| grep -v '^#' \
| sed 's|^|deny |; s|$|;|' \
> /etc/nginx/conf.d/feodo-blocklist.conf
nginx -t && nginx -s reload
Include it in your http or server block with include /etc/nginx/conf.d/feodo-blocklist.conf;. Run hourly. The list rotates — stale blocks are harmless, missing new entries is not.
ufw
#!/bin/bash
curl -sf https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt \
| grep -v '^#' \
| while read ip; do
ufw deny from "$ip" to any
done
Cloudflare (free tier)
#!/bin/bash
# CF_ZONE and CF_TOKEN set as env vars
curl -sf https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt \
| grep -v '^#' \
| while read ip; do
curl -s -X POST \
"https://api.cloudflare.com/client/v4/zones/$CF_ZONE/firewall/access_rules/rules" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"mode\":\"block\",\"configuration\":{\"target\":\"ip\",\"value\":\"$ip\"},\"notes\":\"feodo-c2\"}"
done
Free tier caps at 200 rules per zone. Filter to the recommended subset or prioritize by malware family if you hit the limit.
Why This Exists
I built this because I was tired of tabbing between CISA, abuse.ch, and a dozen bookmarks every time I wanted a quick check on what was actively being exploited. The intel was always there — I just needed it in one place without noise.
It's also partially a rebuttal. People assume good threat intel costs money. It doesn't. The expensive platforms are useful for correlation and scale — but the underlying feeds are public. The person standing up their first VPS doesn't need a $50k subscription. They need to know these feeds exist and that there's a one-liner to act on them.
If this saved you time or gave you something to block, coffee is appreciated. The ROI on a $5 coffee that taught you how to block active botnet C2s is hard to argue with.