Skip to content

new: [expansion] ipapi.is lookup module - #927

Merged
adulau merged 1 commit into
MISP:mainfrom
NikolaiT:add-ipapi-is
Oct 14, 2026
Merged

adulau merged 1 commit into
MISP:mainfrom
NikolaiT:add-ipapi-is

Conversation

@NikolaiT

Copy link
Copy Markdown
Contributor

Adds ipapi.is Lookup (misp_modules/modules/expansion/ipapi_is.py), an expansion and hover module for ip-src and ip-dst attributes. It queries the ipapi.is API and returns misp_standard results:

  • a geolocation object (country code, country, region, city, zip code, coordinates) that locates the attribute;
  • an asn object (AS number, organisation, description, announced route, country) that includes it;
  • an ipapi-is-ip object that describes it: the detection flags that are set (VPN, proxy, Tor, datacenter, abuser, crawler, mobile, satellite, anycast), the VPN provider, type and last-seen time, the hosting provider, the crawler name, the company with its abuser score, the AS abuser score, the abuse contact and the registry.

api_key is optional. A free ipapi.is account gets 1,000 requests a day with the full response. Without a key the API answers 30 requests a day per IP address with location and network owner only. The module then returns just those, and the comment of the ipapi-is-ip object says the detection flags were not included, so a missing flag is not mistaken for a clean address.

The key is sent in the JSON body of a POST request, never in the URL. Private and reserved addresses are rejected before any request is made. API errors (invalid key, quota, free tier exhausted, a bare 403) are returned as {"error": ...} without retries; the timeout is 10 s.

The ipapi-is-ip template is proposed in MISP/misp-objects#541. Like ipgeolocation, the module carries the template's UUID, version, meta-category and description, and sets each attribute's type and correlation itself, so the object is accepted before a PyMISP release ships the template.

Testing:

  • tests/test_ipapi_is.py: 38 pytest cases with requests.post mocked: a full VPN exit response, the datacenter and Tor example from the ipapi.is docs, each flag on its own, the crawler name, an unknown location, keyless responses, a bogon, API and HTTP errors and a timeout, invalid input, the key in the JSON body and not in the URL, and no key field without a key.
  • black, isort and flake8 (the versions in poetry.lock) are clean.
  • The module loads in misp-modules, and I checked it by hand against the live API with and without a key.

Docs: the entries in documentation/README.md, documentation/mkdocs/expansion.md and documentation/mkdocs/index.md are the documentation/generate.py output for this module; the README.md line is added by hand like the others. The logo is documentation/logos/ipapi_is.png.

Disclosure: I run ipapi.is.

@adulau

adulau commented Oct 14, 2026

Copy link
Copy Markdown
Member

Thank you. FYI, the documentation is generated from the JSON file per module. Feel free to add one.

@adulau
adulau merged commit 0691168 into MISP:main Oct 14, 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