XposedOrNot for OpenCTI

Live  Merged in OpenCTI-Platform/connectors#6999

The XposedOrNot internal-enrichment connector adds data-breach exposure to Email-Addr observables in OpenCTI: which breaches an address appears in, when, how many records were exposed, which data classes leaked and how passwords were stored. It ships in the official OpenCTI-Platform/connectors repository and works without an API key.

What you get

For a breached address the connector enriches the observable in place and attaches one Note:

  • Labels data-breach and, when at least one breach stored passwords in plaintext, plaintext-password-exposure. Both are refreshed on every run; your other labels are kept.
  • A markdown Note with the breach table (newest 50 by default): breach name, date, records exposed, affected domain, industry, exposed data classes, password-storage risk, verification status and a short description, plus first and latest exposure years and totals. Re-enriching updates the same Note instead of adding a second one.
  • An external reference to xposedornot.com on the observable.
  • An optional score: the XposedOrNot risk score (0 to 100) is written to the observable only when XPOSEDORNOT_UPDATE_SCORE=true. See the score note below before switching it on.

A clean address (no known breach) completes with the status No known breach exposure for this email address (XposedOrNot) and changes nothing. The connector is playbook-compatible: when there is nothing to add, the incoming bundle is handed back unchanged so the next step still runs.

Requirements

  • OpenCTI Platform 7.261026.0 or newer.
  • No XposedOrNot account or API key. An optional commercial key raises the rate limits.

Installation

Docker (recommended): add the connector service to the docker-compose.yml of your OpenCTI stack, next to your other connectors, then start it.

connector-xposedornot: image: opencti/connector-xposedornot:latest environment: - OPENCTI_URL=${OPENCTI_URL} - OPENCTI_TOKEN=${OPENCTI_TOKEN} - CONNECTOR_ID=c6b0f5f2-c47e-4d49-92a9-10371b40f5d8 - CONNECTOR_NAME=XposedOrNot - CONNECTOR_SCOPE=Email-Addr - CONNECTOR_AUTO=false - CONNECTOR_MAX_TLP=amber - CONNECTOR_LOG_LEVEL=error - XPOSEDORNOT_API_KEY= - XPOSEDORNOT_TLP_LEVEL=amber - XPOSEDORNOT_MAX_NOTE_BREACHES=50 - XPOSEDORNOT_UPDATE_SCORE=false restart: always depends_on: - opencti
docker compose up -d connector-xposedornot

Use a fresh UUIDv4 for CONNECTOR_ID if you run more than one instance.

Manual (Python 3, from a clone of the connectors repository):

cd internal-enrichment/xposedornot pip3 install -r src/requirements.txt cp config.yml.sample config.yml python3 -m src

Edit config.yml before the last step: set opencti.url and opencti.token; the remaining keys mirror the environment variables in the table below.

Confirm it is running

In OpenCTI open Data → Ingestion → Connectors. XposedOrNot should be listed as an internal enrichment connector with a green status and Email-Addr in its scope. If it is missing, check the container logs:

docker compose logs -f connector-xposedornot

First enrichment

  1. Open any Email-Addr observable (Observations → Observables), or create one.
  2. Click the enrichment icon in the top-right toolbar and pick XposedOrNot.
  3. Within a few seconds the observable gains the data-breach label, an external reference and a Note tabulating each breach. If the address is clean, the work completes with no changes.

To enrich automatically, set CONNECTOR_AUTO=true. Keep it off on the keyless API: the limits below are easy to hit with automatic enrichment, so configure an API key first.

Configuration

None required. The defaults use the free, keyless community API. The variables you are most likely to change:

VariableDefaultWhat it does
XPOSEDORNOT_API_KEYempty Optional key from plus.xposedornot.com. Switches to the commercial Plus API with higher rate limits.
CONNECTOR_MAX_TLPamber Highest TLP an observable may carry and still be enriched. The email address leaves your platform, so this gates what may be sent.
XPOSEDORNOT_TLP_LEVELamber TLP marking applied to the Note. The Note also inherits every marking of the source observable.
XPOSEDORNOT_UPDATE_SCOREfalse Write the XposedOrNot risk score to the observable's score. Community API only; it overwrites the existing score.
XPOSEDORNOT_MAX_NOTE_BREACHES50 How many breaches the Note tabulates, newest first. 0 renders all of them.
CONNECTOR_AUTOfalse Enrich every new Email-Addr automatically. Needs an API key in practice.
CONNECTOR_LOG_LEVELerror debug, info, warn or error.

The full reference, including XPOSEDORNOT_API_BASE_URL, is in the connector's README.

Score semantics: OpenCTI usually reads an observable's score as a level of threat. The XposedOrNot risk score measures how exposed a victim address is across known breaches; a heavily breached address scores 100 without being malicious. That is why the score is off by default. Think twice before routing scored Email-Addr observables into detection-oriented workflows or feeds.

Rate limits

Keyless community API: 2 requests/second, 25/hour, 100/day per IP. HTTP 429 responses are retried twice with backoff honouring Retry-After; if the limit is still hit, that single enrichment is reported in error and the connector keeps running. The optional commercial key raises these limits.

Troubleshooting

Set CONNECTOR_LOG_LEVEL=debug and watch the connector logs. The email address and API key are redacted from every message.

Log messageMeaning
XposedOrNot rate limited; backing offExpected under keyless bursts. Configure a key for volume.
XposedOrNot: still rate limited after retriesThree attempts exhausted; only that enrichment failed.
XposedOrNot: request rejected (check the API key)The Plus API refused the key in XPOSEDORNOT_API_KEY.
XposedOrNot: redirect refusedThe base URL redirected. Point XPOSEDORNOT_API_BASE_URL at the endpoint that answers directly (https only).
XposedOrNot request failedNetwork or TLS failure between the connector and the API.
Observable not enriched, no errorIts TLP is above CONNECTOR_MAX_TLP, it is not an Email-Addr, or the address has no known breach.
Privacy: only the observable's email address is sent, over TLS, to xposedornot.com (or to the Plus endpoint when a key is set); nothing else about the observable or the bundle leaves your platform. Breach exposure tied to an email address is personal information: gate it with CONNECTOR_MAX_TLP, mark results restrictively and use them within lawful, authorised investigations. See our privacy policy.

Links