Skip to content

Scanner Checks

Fabrizio Salmi edited this page May 15, 2026 · 1 revision

Scanner Checks

The scanner runs automated checks against each target asset. All checks are grouped by category and each finding maps to one or more NIS2 Art. 21 sub-paragraphs.

Checks run in parallel using asyncio. The default concurrency is 20 tasks per scan and can be adjusted per scan or via org-level defaults.


Port Scanning

An async TCP connect probe (2-second timeout per port) is performed against each host.

Port Service Finding condition
21 FTP Open — cleartext file transfer
22 SSH Open — noted (management exposure)
23 Telnet Open — cleartext remote access
53 DNS Open — DNS resolver exposure
80 HTTP Open — cleartext web
443 HTTPS Open — noted (expected)
445 SMB Open — Windows file-sharing exposure
3306 MySQL Open — database port exposed to network
3389 RDP Open — Windows Remote Desktop exposure
5432 PostgreSQL Open — database port exposed to network
6379 Redis Open — in-memory store exposed to network
8080 HTTP alternate Open — cleartext web on alternate port
8443 HTTPS alternate Open — noted
27017 MongoDB Open — database port exposed to network

Findings are generated for: exposed management ports (SSH, RDP, Telnet, SMB), cleartext protocols (FTP, HTTP, Telnet), and publicly reachable database ports (MySQL, PostgreSQL, Redis, MongoDB).

NIS2 mapping: Art. 21(e) — secure acquisition, 21(h) — cryptography and network security.


TLS/SSL

TLS checks connect to port 443 (and 8443 if open) using Python's ssl module.

Check What it tests
Protocol version Reads the negotiated TLS version from the handshake
Deprecated version probing Attempts forced TLS 1.0 and TLS 1.1 connections individually; flags if the server accepts them
Cipher suite Reports the cipher negotiated on the primary connection
Certificate chain Validates chain trust using the system CA store
Hostname match Verifies the certificate covers the requested hostname
Certificate expiry Calculates days to expiry; flags at 30 days (warning) and 0 days (critical)

Finding conditions:

  • TLS 1.0 or TLS 1.1 accepted → high severity
  • Self-signed or untrusted certificate → high severity
  • Certificate expiring within 30 days → medium severity; expired → critical
  • Hostname mismatch → critical severity

NIS2 mapping: Art. 21(h) — cryptography.


HTTP Security Headers

The scanner performs an HTTP GET to the root path of each domain and inspects the response headers.

Required headers

Header Purpose Finding when absent
Strict-Transport-Security Enforce HTTPS, prevent protocol downgrade (HSTS) Medium
Content-Security-Policy Restrict resource origins, mitigate XSS and injection Medium
X-Frame-Options Prevent clickjacking via iframe embedding Medium

Information-leaking headers

The scanner captures these headers when present and includes them in the finding detail. Presence is informational — they disclose technology stack details that aid attackers.

Header What it leaks
Server Web server name and version
X-Powered-By Runtime or framework
X-AspNet-Version ASP.NET version
X-Generator CMS or generator

NIS2 mapping: Art. 21(e) — secure acquisition and development.


DNS Security

DNS checks use dnspython and run in a thread executor (DNS is blocking). Checks only run when the target is a domain, not an IP address or CIDR range.

Check Method Finding condition
DNSSEC Queries for DNSKEY records Not found → informational
Zone transfer (AXFR) Resolves NS records, then attempts AXFR against each nameserver Transfer succeeds → high severity
SPF Queries TXT records for v=spf1 Not found → medium severity
DMARC Queries TXT records at _dmarc.<domain> for v=DMARC1 Not found → medium severity

AXFR (Zone Transfer): a successful zone transfer discloses the complete DNS zone — all hostnames, IP addresses, and record types — to an unauthenticated external requester. This is consistently rated high severity.

NIS2 mapping: Art. 21(e) — secure network configuration.


Legal Compliance (Italy)

Legal checks use a headless Chromium instance (playwright) to render the page and analyse the DOM. They run only on root domains and www. subdomains — not on IP addresses, API subdomains, or service endpoints.

Check What it looks for Regulation
P.IVA (VAT number) An 11-digit Italian VAT pattern in the rendered page Italian law for commercial sites
Privacy policy Keywords: privacy policy, informativa privacy, informativa sulla privacy GDPR Art. 13/14, D.Lgs 196/2003
Cookie banner Keywords: cookie, accetta, accept cookies, manage cookies, cookie consent patterns ePrivacy Directive, Garante cookie guidelines

These checks do not constitute a legal audit. Absence of the keyword pattern does not prove non-compliance (the page may present the information in an unexpected way). Presence does not guarantee compliance with content requirements.

NIS2 mapping: Art. 21(a) — risk policies and governance.


Secrets Detection

The scanner fetches the HTML body of HTTP and HTTPS responses and scans for patterns that indicate exposed secrets.

Pattern What it detects
AKIA[0-9A-Z]{16} AWS IAM access key ID
aws_secret_access_key\s*=\s*\S+ AWS secret access key
-----BEGIN (RSA|EC|DSA) PRIVATE KEY----- Private key in PEM format
ghp_[a-zA-Z0-9]{36} GitHub personal access token
api[_-]?key\s*[:=]\s*.{20,} Generic API key assignment
eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+ JWT in page source

All detected patterns are flagged as high or critical severity. The raw secret value is redacted in the finding output — only the pattern type and location are recorded.

NIS2 mapping: Art. 21(e) — secure development practices.


WHOIS

WHOIS lookups retrieve registration data for domain assets.

Check What it reads Finding condition
Registrar Domain registrar name Informational
Expiry date Domain registration expiry Expiring within 30 days → warning; expired → critical
Name servers Authoritative NS records Informational
Registration country Country of the registrant Informational

WHOIS data is included in the finding detail for auditor review. Domain expiry is the only check that generates a non-informational finding.


Compliance Engine

After all checks complete, the compliance engine:

  1. Assigns each finding a NIS2 Art. 21 sub-paragraph mapping based on the check category.
  2. Calculates a per-article compliance score (0–100) weighted by open finding severity.
  3. Produces the compliance_matrix JSON snapshot stored on the scan record.
  4. Computes the overall compliance_score as a weighted average across all articles.

The scoring formula:

  • Base score: 100
  • Deductions: critical −40, high −20, medium −10, low −5, info −1
  • Floor: 0 (score cannot go below zero)
  • Per-article scores are averaged to produce the overall score

Score interpretation is intentionally conservative — a score of 70 means there are material open findings, not that the organisation is 70% compliant with the directive.

Clone this wiki locally