Skip to content

Scanner Checks

The scanner runs automated checks against each target. Checks are grouped by category and mapped to NIS2 Art. 21 articles.

Port Scanning

Scans for open ports on the following services:

PortService
21FTP
22SSH
23Telnet
53DNS
80HTTP
443HTTPS
445SMB
3306MySQL
3389RDP
5432PostgreSQL
6379Redis
8080HTTP Alternate
8443HTTPS Alternate
27017MongoDB

Each port is probed with an async TCP connection (2-second timeout). Findings are generated for exposed management ports (SSH, RDP, Telnet, SMB) and cleartext protocols (FTP, HTTP, Telnet), as well as exposed database ports (MySQL, PostgreSQL, Redis, MongoDB).

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

TLS/SSL

  • Protocol version detection: connects to port 443/8443 and reads the negotiated TLS version.
  • Weak version probing: attempts connections forcing TLS 1.0 and TLS 1.1 individually. Flags them if the server accepts these deprecated versions.
  • Cipher detection: reports the cipher suite negotiated on the primary connection.
  • Certificate validation: uses Python's ssl module to retrieve the peer certificate. Checks chain trust and hostname match.

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

HeaderPurposeFinding when absent
Strict-Transport-SecurityEnforce HTTPS, prevent protocol downgrade (HSTS)Medium
Content-Security-PolicyRestrict resource origins, mitigate XSS and injectionMedium
X-Frame-OptionsPrevent clickjacking via iframe embeddingMedium

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.

HeaderWhat it leaks
ServerWeb server name and version
X-Powered-ByRuntime or framework
X-AspNet-VersionASP.NET version
X-GeneratorCMS or generator

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

DNS Security

DNS checks use dnspython and run in a thread executor to avoid blocking the async loop.

  • DNSSEC: queries for DNSKEY records on the domain. If present, DNSSEC is reported as enabled.
  • Zone transfer (AXFR): resolves the domain's NS records, then attempts an AXFR transfer against each nameserver. Flags the domain if any nameserver allows it.
  • SPF: queries TXT records for the domain and looks for a record starting with v=spf1.
  • DMARC: queries TXT records at _dmarc.<domain> and looks for a record starting with v=DMARC1.

DNS checks are only run when the target is a domain (not an IP address or CIDR range).

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

Legal checks use playwright (headless browser) to render the page and analyze the DOM. They only run on root domains and www. subdomains, not on IP addresses or service subdomains.

  • P.IVA (VAT number): searches for an Italian VAT number pattern (11 digits) in the page content. Required by Italian law for commercial sites.
  • Privacy policy: searches for keywords like "privacy policy", "informativa privacy" in the rendered page.
  • Cookie banner: searches for cookie consent keywords ("cookie", "accetta", "accept cookies", "manage cookies", etc.) in the rendered page.

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

Secrets Detection

Scans the HTML body of HTTP responses for leaked secrets. The scanner checks for these patterns (defined in secrets.py):

PatternDescription
AKIA[0-9A-Z]{16}AWS access keys
aws_secret_access_key = ...AWS secret keys
-----BEGIN (RSA|EC|DSA) PRIVATE KEY-----Private keys (RSA, EC, DSA)
ghp_[a-zA-Z0-9]{36}GitHub personal access tokens
api[_-]?key[:=] ...Generic API key assignments (20+ character values)
eyJ... (three Base64 segments separated by dots)JWT tokens in page source

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

WHOIS

  • Domain expiry: uses python-whois to look up the domain's expiration date. Flags domains expiring within 30 days.

WHOIS checks are only run when the target is a domain.

WAF/CDN Detection

Detects the presence of Web Application Firewalls and CDN providers by matching response headers and cookie values against known indicators:

  • Cloudflare (cf-ray header, __cfduid cookie)
  • Akamai (x-akamai header)
  • AWS CloudFront (x-amz-cf-id header)
  • Fastly (x-fastly header)
  • Incapsula/Imperva (incap_ses, visid_incap cookies)
  • Sucuri (x-sucuri-id header)

Sensitive Files

Probes for files that should not be publicly accessible:

PathDetection Logic
/.git/HEADReturns 200 and body contains ref: refs/
/.envReturns 200 and body contains =

Responses are validated to avoid false positives from custom 404 pages that return HTTP 200.

security.txt

Checks for the presence of /.well-known/security.txt per RFC 9116. Falls back to /security.txt if the well-known path returns a non-200 status.

Subresource Integrity

Parses the HTML body for external <script> tags (those with an src attribute pointing to a different host). Flags scripts that do not include an integrity attribute (SRI).

Analyzes Set-Cookie headers in the HTTP response:

  • Secure flag: cookie should only be sent over HTTPS.
  • HttpOnly flag: cookie should not be accessible via JavaScript.
  • SameSite attribute: CSRF protection.

Compliance Engine

After the checks finish, the compliance engine turns findings into a score.

It is computed per host, then averaged over the hosts that answered — not per NIS2 article. Each host starts at 100 and every finding on it deducts:

SeverityDeduction
CRITICAL−50
HIGH−20
MEDIUM−10
LOW−5
INFOnone — informational findings never move the score

A host score is floored at 0, and the scan's score is the mean of the host scores over active_hosts (the hosts that responded).

A scan that assessed nothing has no score at all. Both ways that happens — no target resolved, or targets that never answered — used to produce 100/100, which reads as a clean bill of health for a scan that observed nothing. The score is now null, carrying the reason instead.

Alongside the score the engine stores a compliance_matrix snapshot on the scan, mapping findings to the Art. 21(2) sub-paragraphs.

Read the number conservatively: 70 means there are material open findings, not that the organisation is 70% compliant with the directive.