Threat Intelligence
Leak detection, credential exposure, dark web mentions, and email reputation.
Implemented in farsight/modules/threat_intel.py, class ThreatIntel. Enabled with --threat-intel/-t (or --all/--modules threat).
What always runs
Two checks run regardless of depth or configuration:
- PhoneBook.cz scraping — a public source for leaked emails associated with the domain, no API key needed.
- Dark web alternative check (
_check_dark_web_alternative) — runs automatically whenever IntelX isn’t configured. This is a pattern-matching fallback against a hardcoded list of historical breaches, explicitly labeled with low/medium confidence in its output rather than presented as equivalent to a real dark-web search. It exists so the module still produces something on a fully keyless install, not nothing.
Depth-gated checks
- Depth ≥2: if IntelX is configured, runs a proper IntelX search (leaks/pastes/darknet mentions) and an IntelX phonebook search (related selectors — other emails, domains, or identifiers linked to the target); if LeakPeek is configured and emails are available, checks each against known breach data; computes email reputation for every email found so far.
- Depth 3: if IntelX is configured, additionally searches its
documentsbucket. If the scan found domain-associated emails but none were explicitly provided, checks up to the first 3 against HaveIBeenPwned as a supplementary pass — capped at 3 specifically to avoid overloading that check for domains with many discovered emails.
The IntelX cache: avoiding repeat credit spend
IntelX bills a credit per search, but fetching results for an existing search ID is free. _cached_intelx_search (backed by farsight/utils/intelx_cache.py) hashes the query parameters to a cache key: an identical repeat query either serves already-cached results directly, or — if the cached entry only has a search ID but no fresh results — re-uses that search ID against the free result endpoint instead of starting a new (billed) search. The cache defaults to a 6-hour TTL (intelx_cache_ttl). This matters in practice: iterating on a scan against the same domain during development, or re-running a scan you already ran that day, doesn’t silently burn through a limited IntelX quota.
Email reputation scoring
get_email_reputation() computes a 0–100 risk score per discovered email, independent of any external breach-database lookup — this is a heuristic based on the email and its domain alone:
score += 40 if the domain is < 30 days old (WHOIS creation date)
score += 20 if the domain is 30-90 days old
score += 30 if the domain is a known disposable/temp-mail provider
score += 15 if the username is more than 50% digits
score += 10 if the username is a generic role account (admin, info,
sales, support, noreply, contact)
Score bands map to a label: >=70 high risk, >=40 medium risk, >=10 low risk, otherwise good. A brand-new domain paired with a disposable-provider username can hit 70+ purely from those two signals — this is intentionally a fast heuristic, not a replacement for an actual breach-database check.
Output shape
{
"leaks": [{ "source": "phonebook", "emails": ["user@example.com"] }],
"dark_web": [{ "source": "pattern-match", "confidence": "low", "breach": "..." }],
"credentials": [],
"email_reputation": [{ "email": "user@example.com", "reputation": "low risk", "risk_score": 15 }],
"intelx_phonebook": [],
"unique_emails_found": ["user@example.com"],
"total_leaks": 1,
"total_credentials": 0
}
Note that credentials in the report has emails obfuscated (@ → [at]) before being written out — see Reports.