Share an Nmap scan report
Nmap's XML output is machine-readable and unreadable by people; the terminal
output is readable and unpasteable. The bridge has shipped with Nmap for
years and almost nobody uses it — nmap.xsl, which turns the XML into a
clean HTML report with the host table, open ports, and detected service
versions.
The reason nobody uses it is not the stylesheet. It is that the HTML has nowhere to go afterwards, and a network scan is the last artifact anyone wants to drop into a chat window.
Convert and publish
nmap -sV -oX scan.xml 10.0.0.0/24
xsltproc scan.xml -o scan.html
curl -fsS -X POST "https://commareports.com/api/v1/reports" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html scan.html \
--arg title "Perimeter scan — $(date +%Y-%m-%d)" \
'{title: $title, html: $html, visibility: "private"}')"
Scan only what you are authorized to scan. Assuming that box is ticked, the sharing question is the one this page is about.
Set visibility first, not later. An open-port inventory with service
versions is a starting point for an attacker. Create it private, then widen
to your team, an email domain, or named reviewers. See the
sharing model.
The findings that are not findings
Most of a recurring scan is noise you already understand — and understand again, from scratch, every quarter, because the explanation lived in a DM. Anchored comments fix exactly that:
- "tcp/8443 — internal load balancer, expected."
- "This host is decommissioned, DNS record is stale, ticket OPS-88."
- "New since last scan. Nobody owns this. Escalating."
Each one attaches to the host it is about and survives the next scan, because revisions carry the threads forward. See commenting on HTML.
Recurring scans
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html scan.html '{html: $html}')"
One report id per scope. The diff between two revisions answers the only question a recurring scan exists to answer: what is open now that was not open before. A scheduled routine can run it without anyone remembering to.
Limits
- HTML body: 5 MB. A
/16with service detection will exceed it — split by subnet and publish one report per scope, which is how you would want to read it anyway. - Scripts run, sandboxed:
allow-scripts, noallow-same-origin. - 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.