[PR #184] feat(imports): add nmap XML importer #3440

Open
opened 2026-06-18 17:31:10 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/reconurge/flowsint/pull/184
Author: @rachit367
Created: 6/9/2026
Status: 🔄 Open

Base: mainHead: feat/nmap-xml-importer


📝 Commits (1)

  • f9100ba feat(imports): add nmap XML importer

📊 Changes

8 files changed (+314 additions, -4 deletions)

View changed files

📝 flowsint-api/app/api/routes/sketches.py (+4 -2)
📝 flowsint-app/src/components/sketches/import-sheet.tsx (+1 -1)
📝 flowsint-core/pyproject.toml (+1 -0)
📝 flowsint-core/src/flowsint_core/imports/file_parser.py (+4 -1)
flowsint-core/src/flowsint_core/imports/nmap/__init__.py (+3 -0)
flowsint-core/src/flowsint_core/imports/nmap/parse_nmap.py (+150 -0)
flowsint-core/tests/import/nmap/test_nmap_import.py (+140 -0)
📝 uv.lock (+11 -0)

📄 Description

What

Adds an nmap XML importer so an existing scan can be imported into a sketch, instead of re-scanning a target or adding ports by hand.

Closes #107

Why

From the issue: during assessments people often run nmap manually with specific flags, and naabu can also export in nmap XML. Letting Flowsint ingest that XML enriches a sketch with the hosts/ports already discovered. This reuses the existing two-phase import pipeline (analyze → execute) — no new infrastructure.

How it plugs in

The import pipeline dispatches parsers by file extension (flowsint_core/imports/file_parser.py) and each parser is a function returning a FileParseResult of typed entities + edges, which the pipeline persists. The new parser follows that exact contract (same shape as the existing JSON parser).

  • flowsint_core/imports/nmap/parse_nmap.py (new) — parse_nmap_xml() turns an nmap report into:
    • Ip entities (one per up host; down hosts skipped; IPv4 preferred, IPv6 supported, MAC ignored)
    • Port entities (number, protocol, state, service, and a banner composed from service product/version/extrainfo)
    • IP -[HAS_PORT]-> Port edges (the same relationship label the ip_to_ports enricher uses)
  • Wiring: .xml added to ALLOWED_EXTENSIONS (core dispatcher) + the analyze route's filename validation (flowsint-api/.../sketches.py) + the import sheet's accepted extensions (flowsint-app/.../import-sheet.tsx). Ip and Port already exist, so no type changes were needed.

Security

Import files are untrusted, so the XML is parsed with defusedxml (new flowsint-core dependency) to prevent XXE / billion-laughs attacks. Element type hints still come from the stdlib (identical types, not a parsing path).

Testing

uv run --package flowsint-core pytest flowsint-core/tests/import/ -q
56 passed   # 10 new nmap tests + existing import suite, no regressions

New tests (pure-parse, no DB): IP/port extraction, port fields + banner composition, HAS_PORT edges, down-host skipping, IPv6, invalid-port skipping, empty/invalid XML handling, and dispatch through parse_import_file.

Scope note: this maps the core of an nmap scan (hosts + ports + service info). NSE script output (which could map to the existing Script type) is intentionally left out to keep the PR focused; happy to add it as a follow-up if wanted.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/reconurge/flowsint/pull/184 **Author:** [@rachit367](https://github.com/rachit367) **Created:** 6/9/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/nmap-xml-importer` --- ### 📝 Commits (1) - [`f9100ba`](https://github.com/reconurge/flowsint/commit/f9100ba15ee69ea35db912b553877fb0da089f4a) feat(imports): add nmap XML importer ### 📊 Changes **8 files changed** (+314 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `flowsint-api/app/api/routes/sketches.py` (+4 -2) 📝 `flowsint-app/src/components/sketches/import-sheet.tsx` (+1 -1) 📝 `flowsint-core/pyproject.toml` (+1 -0) 📝 `flowsint-core/src/flowsint_core/imports/file_parser.py` (+4 -1) ➕ `flowsint-core/src/flowsint_core/imports/nmap/__init__.py` (+3 -0) ➕ `flowsint-core/src/flowsint_core/imports/nmap/parse_nmap.py` (+150 -0) ➕ `flowsint-core/tests/import/nmap/test_nmap_import.py` (+140 -0) 📝 `uv.lock` (+11 -0) </details> ### 📄 Description ## What Adds an **nmap XML importer** so an existing scan can be imported into a sketch, instead of re-scanning a target or adding ports by hand. Closes #107 ## Why From the issue: during assessments people often run nmap manually with specific flags, and naabu can also export in nmap XML. Letting Flowsint ingest that XML enriches a sketch with the hosts/ports already discovered. This reuses the existing two-phase import pipeline (analyze → execute) — no new infrastructure. ## How it plugs in The import pipeline dispatches parsers by file extension (`flowsint_core/imports/file_parser.py`) and each parser is a function returning a `FileParseResult` of typed entities + edges, which the pipeline persists. The new parser follows that exact contract (same shape as the existing JSON parser). - `flowsint_core/imports/nmap/parse_nmap.py` (new) — `parse_nmap_xml()` turns an nmap report into: - `Ip` entities (one per *up* host; down hosts skipped; IPv4 preferred, IPv6 supported, MAC ignored) - `Port` entities (`number`, `protocol`, `state`, `service`, and a `banner` composed from service `product`/`version`/`extrainfo`) - `IP -[HAS_PORT]-> Port` edges (the same relationship label the `ip_to_ports` enricher uses) - Wiring: `.xml` added to `ALLOWED_EXTENSIONS` (core dispatcher) + the analyze route's filename validation (`flowsint-api/.../sketches.py`) + the import sheet's accepted extensions (`flowsint-app/.../import-sheet.tsx`). `Ip` and `Port` already exist, so no type changes were needed. ## Security Import files are untrusted, so the XML is parsed with **`defusedxml`** (new `flowsint-core` dependency) to prevent XXE / billion-laughs attacks. Element type hints still come from the stdlib (identical types, not a parsing path). ## Testing ``` uv run --package flowsint-core pytest flowsint-core/tests/import/ -q 56 passed # 10 new nmap tests + existing import suite, no regressions ``` New tests (pure-parse, no DB): IP/port extraction, port fields + banner composition, `HAS_PORT` edges, down-host skipping, IPv6, invalid-port skipping, empty/invalid XML handling, and dispatch through `parse_import_file`. > Scope note: this maps the core of an nmap scan (hosts + ports + service info). NSE script output (which could map to the existing `Script` type) is intentionally left out to keep the PR focused; happy to add it as a follow-up if wanted. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-06-18 17:31:10 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/flowsint#3440