← Back to Guides
How the Scanner Works

Scanner Technical Specification

Written for developers, agencies and managed service providers evaluating Biz Secure Online on behalf of clients. It states what the scanner runs, how it scores, how it behaves when a check cannot complete, and what it does not do.

Everything below describes the engine in production as at 15 September 2026.


Scanning tools used

  1. Nuclei (projectdiscovery/nuclei) - template-driven vulnerability scanning
  2. WPScan - WordPress core, plugin and theme enumeration
  3. Nmap - TCP port and service detection
  4. Playwright (Firefox) - real-browser retrieval when an HTTP client is refused
  5. Node tls - certificate retrieval and protocol negotiation
  6. RDAP, with whois CLI fallback - domain registration
  7. Node dns resolver - SPF, DMARC, DKIM, CAA, MX, NS
  8. Google PageSpeed Insights API - performance metrics
  9. In-house analysers - HTTP security headers, cookie attributes, on-page SEO, technology fingerprinting

Residential proxy egress is available to the retrieval tiers where a cloud address range is refused outright.


1. Origin reachability (runs first, informs everything after)

Most target sites sit behind a WAF or CDN. That layer answers requests it dislikes, and its response is not the customer's server. A scanner that does not model this will parse a challenge page and report it as the customer's configuration.

Reachability is established once, before the analysers run, and passed to all of them.

Retrieval ladder

  1. Node fetch with a browser User-Agent. HEAD, retried as GET on 405 or 501.
  2. Playwright Firefox, real browser fingerprint.
  3. Playwright Firefox via residential proxy.

Block detection is by body fingerprint, then challenge headers (cf-mitigated, sg-captcha and similar), then status code against a WAF set (401, 403, 406, 409, 418, 429, 503). There is deliberately no blanket status >= 400 rule: a 405 is a method rejection, not a block, and treating it as one launches a browser tier unnecessarily.

Three states, not two. reached is true, false (blocked, with the provider named) or null (never established, for example the headers tool timed out). Consumers test for an explicit true before making any claim about the origin.


2. Network and port scanning (Nmap)

  • -sT -sV --version-intensity 2 -T4 --open --host-timeout 45s
  • 21 ports, fixed: 21, 22, 25, 53, 80, 110, 143, 443, 465, 587, 993, 995, 1433, 3306, 3389, 5432, 8080, 8443, 8888, 9090, 27017
  • Service and version detection on each open port
  • Not a 65,535 port sweep. A service on an unlisted port is not found and the report does not imply otherwise.
  • Edge port suppression: where a CDN is detected, that provider's published proxy ports (for Cloudflare: 2052, 2053, 2082, 2083, 2086, 2087, 2095, 2096, 8080, 8443, 8880) are reported as belonging to the edge, not as customer exposure. No suppression set contains a database or remote-access port, so the failure direction is under-suppression.

3. TLS (Node tls)

  • Certificate retrieval with rejectUnauthorized: false, so an invalid certificate can still be inspected rather than refused
  • Issuer, subject, validFrom and validTo, days until expiry
  • Protocol negotiation probed individually: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3
  • Managed-certificate classification, so a 90-day CDN certificate is not reported as an imminent expiry
  • Proxy fallback for both certificate and protocol probes

Not performed: chain-of-trust validation, hostname and SAN matching, revocation checking, cipher suite enumeration, and letter grading. Validity is currently computed from the certificate dates alone. A certificate we report as valid may still produce a browser warning. This is scheduled work and is stated here rather than left for you to discover.


4. Web vulnerabilities (Nuclei)

Template tags enabled:

cves, exposure, misconfiguration, default-logins, fuzzing,
technologies, network, exposed-panels, exposed-tokens, iot
  • Rate limited to 20 requests per second. A scan is not a load test.
  • Per-request timeout 10s. Web phase budget 840s, followed by a network phase of 300s against discovered ports, both inside a 1200s per-tool cap so a partial result survives rather than being discarded.
  • Findings carry template ID, severity, CVSS where the template provides one, CVE and CWE references, and matched-at location.
  • The dns tag is deliberately not enabled. DNS is checked directly (section 6) rather than inferred from templates, which previously produced findings with no actionable content.

Coverage follows the enabled tags and the upstream template set. We do not claim a fixed catalogue of vulnerability classes, because the catalogue is Nuclei's and it changes weekly.


5. HTTP security headers

Six headers, evaluated by value rather than by presence:

Header Weight Passing condition
Strict-Transport-Security 3 max-age present and greater than zero
Content-Security-Policy 2 non-empty
X-Frame-Options 2 DENY or SAMEORIGIN
X-Content-Type-Options 2 nosniff
Referrer-Policy 1 non-empty and not unsafe-url
Permissions-Policy 1 non-empty
  • max-age=0 disables HSTS and is scored as absent, not as configured
  • max-age below 86400 passes but raises a separate low-severity finding
  • HSTS is skipped on plain HTTP, where a browser ignores it, and its weight is removed from the denominator so an HTTP site cannot score higher than the same site on HTTPS
  • Cookies collected from the same responses are checked for Secure, HttpOnly and SameSite, with session-cookie patterns held to a stricter standard than analytics cookies

6. DNS and email authentication

  • SPF - presence, qualifier (-all, ~all, ?all, +all), duplicate records (a permanent error), and a top-level lookup count against the 10-lookup limit
  • DMARC - policy, subdomain policy (sp), pct, reporting address (rua)
  • DKIM - probing of 13 common selector names
  • CAA, MX, NS

enforcing requires all three conditions: a policy of quarantine or reject, and pct not equal to 0, and sp not none. A record reading p=reject; pct=0 applies to no mail, and p=reject; sp=none leaves every subdomain spoofable. Both are p=none in effect and are reported as such.

DKIM absence is never asserted. Selectors cannot be enumerated from outside; finding none means the common names were not found.

CAA is three-state: present, genuinely absent, or not checked. A resolver returning ENODATA is recorded as not checked rather than as an absent record.


7. Failure semantics

This section is the one most worth reading, because it is where scanners usually differ in practice rather than in feature lists.

  • A check that could not complete is reported as not measured. It is never reported as a passing result, and never as a finding.
  • Findings from a section we could not verify are still shown, marked unverified, at info severity with a risk score of zero.
  • A failed tool is distinguished from a tool that found nothing. A nuclei run that did not complete does not produce "0 vulnerabilities found".
  • A connection failure is not narrated as a WAF block. If no edge provider was detected, the report says the request did not complete.
  • Every AI-generated section of the report is given the measured/unmeasured state explicitly and instructed not to characterise sections that were not measured.

8. Risk scoring

Security score (1-100), from a base of 100:

  • Vulnerability severity: Critical -25, High -15, Medium -8, Low -3
  • WordPress-specific vulnerabilities: -5 each, additional
  • High-risk open ports: -15 each
  • Header score contributes 30% of the composite: round(score × 0.7) + round(headerScore × 0.3)
  • Clamped to 1-100

When headers could not be measured, the header term is not estimated and not assumed. Deductions are scaled by 0.7 and no header contribution is added, so such a scan is bounded at 70. An unverified section earns nothing and deducts nothing. Blocking the scanner cannot raise a score.

scoreCoverage is emitted with every result and names the sections that actually contributed: headers, vulnerabilities, ports, DNS. SEO and TLS are reported separately as checks performed, because neither produces findings that move the score.

Severity bands follow CVSS: Critical 9.0-10.0, High 7.0-8.9, Medium 4.0-6.9, Low 0.1-3.9, plus Info.


9. Scan modes

There is one mode. Every scan is a full scan.

A scan_type field is accepted for backwards compatibility and ignored. Typical duration is 10 to 15 minutes, bounded by a 30-minute scan budget and a 20-minute per-tool cap. Concurrency is controlled by a BullMQ worker; machines autoscale with queue depth.


10. Output

  • JSON result document containing findings, per-section raw data, port list, technologies, DNS records, cookie inspection, and score with coverage
  • Per-finding: severity, CVSS and CVE where available, description, and specific remediation steps where we have them. Where we do not, the field says so rather than substituting generic advice.
  • A structured executive summary: verdict, confirmed strengths, up to four attention items each with what, why, action and severity, and a single recommended starting point
  • Per-section narrative insights
  • Shareable report links, revocable, expiring after eight weeks

Programmatic access to start a scan, poll status and retrieve the raw JSON exists and is being productised for partner use. It is not yet generally available. Contact us if you want to be part of that.


Documented limits

  • No authenticated scanning. No credentials, so anything behind a login is out of scope.
  • No business logic testing. Checkout flows, signup processes and application-specific workflows need a human.
  • No client-side JavaScript analysis. Pages are loaded in a real browser to retrieve them, not to audit runtime behaviour. DOM-based XSS is not covered.
  • No subdomain enumeration. One URL per scan.
  • No mail server testing. Public DNS records only.
  • No CORS policy analysis, no directory brute-forcing, and no deep crawl. Content discovery is limited to what the enabled Nuclei exposure templates find.
  • No certificate trust validation, as stated in section 3.
  • A clean result is a scan result, not a certification, and it does not replace a penetration test.

Infrastructure

  • Scan engine and API: Fly.io, Sydney
  • Database: Supabase PostgreSQL, ap-southeast-2
  • Queue: BullMQ on Upstash Redis
  • Container image builds currently run on a Fly builder in Amsterdam, following a capacity issue in Sydney. It compiles images, holds no customer data and serves no traffic. We state it rather than leave a blanket claim standing.

Sub-processors and the data processing agreement list every third party involved.


A note on comparisons

We do not describe this scanner as equivalent to Qualys, Nessus or Acunetix. Those products do authenticated scanning, internal network assessment and deep crawling, and this one does none of those. What it does is external perimeter assessment for small business websites, with explicit handling of the case where the target cannot be reached, and reports written for a non-technical owner.

If a report you can defend in front of a client matters more to you than a long feature list, that is the trade we have made deliberately. The limits above are published for the same reason.

See how exposed your website is, in under 2 minutes.