-
-
Notifications
You must be signed in to change notification settings - Fork 5
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.
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 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.
The scanner performs an HTTP GET to the root path of each domain and inspects the response 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 |
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 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 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.
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 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.
After all checks complete, the compliance engine:
- Assigns each finding a NIS2 Art. 21 sub-paragraph mapping based on the check category.
- Calculates a per-article compliance score (0–100) weighted by open finding severity.
- Produces the
compliance_matrixJSON snapshot stored on the scan record. - Computes the overall
compliance_scoreas 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.