Skip to content

Add XposedOrNot expansion module (email breach lookup, no API key required)#789

Merged
adulau merged 1 commit into
MISP:mainfrom
XposedOrNot:add-xposedornot-expansion
Jul 12, 2026
Merged

Add XposedOrNot expansion module (email breach lookup, no API key required)#789
adulau merged 1 commit into
MISP:mainfrom
XposedOrNot:add-xposedornot-expansion

Conversation

@DevaOnBreaches

Copy link
Copy Markdown
Contributor

This PR adds an expansion/hover module for XposedOrNot — an open, free data-breach search service. Given an email attribute, the module reports which known data breaches the address appears in, with per-breach context.

No API key required. The module works with zero configuration via the free keyless API (rate limits: 2 req/s, 25/hour per IP). An optional api_key (from console.xposedornot.com) switches to the commercial Plus API with higher limits.

Input / output

  • Input: email, email-src, email-dst, target-email, whois-registrant-email
  • Output (misp_standard): one text attribute per breach — value is the breach name; comment carries breach year, records exposed, affected domain, exposed data classes and password-storage risk — preceded by an exposure summary attribute. Correlation is disabled on all returned attributes to avoid correlation-graph noise. (There is currently no fitting object template in misp-objects for per-breach metadata, hence attributes rather than objects; happy to adapt if you prefer an object shape.)

Sample summary attribute for a heavily-breached address:

Email exposed in 202 data breaches (XposedOrNot), first: 2009, latest: 2026, risk: Critical

Sample per-breach comment:

breached: 2026 | 2,699,339 records | domain: sysco.com | exposed: Email addresses; Names; Phone numbers | password risk: unknown | verified: Yes

Behavior notes

  • 404 and empty responses are treated as a clean result ("No breach found…"), not an error.
  • HTTP 429 returns an actionable message pointing at the optional api_key — no blocking retries inside the module server.
  • The email is percent-encoded in the Plus API URL path (covered by a test with User+Tag@Example.com).
  • Privacy: only the queried email address is sent (TLS) to xposedornot.com; nothing else leaves the MISP instance.

Testing

  • tests/test_xposedornot.py — 6 pytest cases (free path with exact-URL assertion, Plus path with URL-encoding, clean 404 + clean 200-empty, 429, HTTP error, invalid input), all mocked, no network required. 8/8 green alongside test_ransomlook.py locally.
  • black --check / isort --check-only clean against the repo config.
  • documentation/generate.py renders the module entry (logo included at documentation/logos/xposedornot.png).
  • End-to-end verified against a locally running misp-modules server: module registers, expansion and hover queries return the outputs above, unsupported attribute types are rejected.

  key required)

New expansion/hover module querying the XposedOrNot data-breach API for
  email
  attributes. Returns one text attribute per breach (year, records exposed,
  domain,
  exposed data classes, password storage risk) plus an exposure summary, in
  misp_standard format with correlation disabled.

  Works with zero configuration via the free keyless API (2 req/s, 25/hour per
  IP);
  an optional api_key config switches to the commercial Plus API with higher
  limits.
  404 and empty responses are treated as a clean result. Includes pytest
  coverage
  (free path, Plus path with URL-encoded email, clean, 429, HTTP errors, invalid
  input) and the logo for the modules documentation site.
@adulau

adulau commented Jul 12, 2026

Copy link
Copy Markdown
Member

Thank you!

@adulau
adulau merged commit 4187b0d into MISP:main Jul 12, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants