HebridesCyber

What we check

Every check listed here runs automatically as part of a Security Score scan. Nothing is hidden behind “proprietary methodology” — this is the actual list, kept in sync with the scanner code.

// scan categories

Every check is read-only and passive by default — no exploit payloads, no destructive requests. The one exception is the optional ZAP active scan, which only runs where it's explicitly configured against a domain you've already verified you own.

🔒

TLS & Certificates

Runs on every scan

Confirms traffic is actually encrypted, and that the certificate and protocol backing that encryption are sound.

  • HTTPS enforced (not just available)
  • Weak protocol detection (TLS 1.0/1.1 still enabled)
  • Certificate expiry — flagged inside 21 days
  • Self-signed certificate detection
  • HSTS presence and max-age adequacy (≥180 days)
🛡️

Security Headers & CSP

Runs on every scan

Checks the response headers that stop a browser doing something dangerous with your content, even after everything else is right.

  • OWASP-recommended header set (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy…)
  • Content-Security-Policy graded A–F — unsafe-inline, unsafe-eval, and wildcard sources all cost points
  • Cookie flags: Secure, HttpOnly, SameSite
  • CORS wildcard origin (Access-Control-Allow-Origin: *)
  • Server/technology version disclosure in headers
📧

DNS & Email Authentication

Runs on every scan

Whether your domain can be spoofed for phishing, and whether your certificate issuance is locked down.

  • SPF record present and correctly scoped
  • DKIM key discovery across the default selectors used by major providers, plus key strength, revocation, and testing-mode checks
  • DMARC record present, and enforcement policy (none / quarantine / reject)
  • MTA-STS policy published and enforced, for domains that receive mail
  • TLS-RPT reporting address configured, so failed mail-TLS connections are visible
  • CAA records restricting which CAs can issue certificates for your domain
  • DNSSEC signing status
📂

Sensitive File Exposure

Runs on every scan

Probes for the specific files that leak credentials or source code when a deployment forgets to exclude them — with false-positive hardening (see below) so a catch-all SPA doesn't get flagged for everything.

  • Git/SVN metadata (.git/HEAD, .git/config, .svn/entries)
  • Environment files (.env, .env.production, .env.backup)
  • Framework config (config.php, wp-config.php.bak, settings.py, database.yml)
  • Backup archives and raw SQL dumps
  • Debug/admin pages (phpinfo, server-status, Symfony profiler, Laravel Telescope)
  • Credential files (.htpasswd, .htaccess) and application logs
  • security.txt presence (credited, not penalised, when found)
🗂️

Directory Listing (Autoindex)

Runs on every scan

Looks for Apache/nginx directory browsing left switched on for uploads, backups, and log folders — scoped narrowly to genuine autoindex pages (an "Index of /…" title plus a Parent Directory link), not just any page that happens to load at a common path.

  • /uploads/, /backup/, /files/, /media/, /downloads/ and similar common paths
  • /logs/, /tmp/, /data/, /wp-content/uploads/
  • Approximate file count when a listing is found
☁️

Cloud Storage Misconfiguration

Runs on every scan

Extracts S3, Azure Blob, and GCS references from your own page source, then tests only those specific buckets for public listing. Never guesses bucket names — that would mean scanning infrastructure you don't own.

  • S3 buckets referenced in your site — tested for public ListBucketResult
  • Azure Blob containers — tested for public EnumerationResults
  • GCS buckets — tested via the same S3-compatible listing check
🔬

Technology Fingerprinting

Runs on every scan

Passive, Wappalyzer-style identification of your stack from headers and page source — no active probing, just pattern matching on what's already public.

  • 40+ frameworks, CMSes, servers, CDNs, and third-party services detected
  • Version extraction where the response reveals one
  • Known-outdated major versions flagged (jQuery, Bootstrap, WordPress, Angular, PHP, Apache)
🔌

Open Ports & Network Exposure

Runs on every scan

Checks which ports are visible to the internet using Shodan's InternetDB — no port-scanning traffic sent to your infrastructure directly.

  • Administrative and database ports that shouldn't be public (SSH, RDP, MySQL, PostgreSQL, MongoDB, Redis)
  • Risk-rated per port with the reason it matters
🖥️

Headless Browser & Page Health

Runs on every scan

Actually loads the page in a real browser engine, the way a visitor would — catches problems a plain HTTP fetch can't see.

  • Page load status and health
  • Mixed content — HTTP resources loaded on an HTTPS page
  • Browser console errors
🛰️

Reconnaissance

Runs on every scan

Passive intelligence gathering from public sources — nothing sent to your infrastructure beyond a standard page request.

  • CVEs Shodan associates with your IP's exposed services
  • Subdomains discovered via Certificate Transparency logs (crt.sh)
🧩

Web Application Security

Runs on every scan

A grab-bag of checks that don't fit a single category but catch some of the most common real-world misconfigurations.

  • robots.txt reviewed for sensitive disallowed paths it inadvertently advertises
  • Dangerous HTTP methods enabled (PUT, DELETE, TRACE)
  • Error pages that leak stack traces or framework internals
  • CORS reflected-Origin misconfiguration (with or without credentials allowed)
  • JavaScript library versions (jQuery, Moment.js, Lodash, Bootstrap, AngularJS…) matched against live CVE data from OSV.dev
  • Cross-origin scripts and stylesheets loaded without a Subresource Integrity hash
🧱

CMS-Specific Deep Scans

Runs when detected

Once fingerprinting identifies WordPress, Joomla, or Drupal, a second pass runs checks specific to that platform.

  • WordPress: XML-RPC exposure, REST API user enumeration, debug.log, readme.html version disclosure, wp-cron.php
  • Joomla: core version disclosure via the administrator manifest, leftover installer files
  • Drupal: core version disclosure via CHANGELOG.txt, update.php reachability, public JSON:API, uid 1 profile enumeration

Active Application Scanning (OWASP ZAP)

Optional (ZAP)

Where a ZAP instance is configured, an active spider/scan can be triggered against the target for deeper coverage than passive checks alone. Off by default — active scanning sends real attack payloads, so it only runs where explicitly enabled for a verified target.

  • Spidering and active vulnerability scanning via a connected ZAP daemon
🔑

Authenticated Scanning

Optional (Agency)

Connect a session cookie or Basic Auth credential for a monitored site and the same header/cookie/CSP/CORS checks re-run against the authenticated page — not a full crawl behind login, and not access-control (IDOR) testing. The one thing this uncovers that nothing else in this suite can: a real session cookie with insecure flags, which is invisible until you're actually logged in.

  • Missing security headers on the authenticated page
  • Session cookies missing Secure/HttpOnly/SameSite — graded more seriously than the same issue on a public page
  • CSP and CORS misconfiguration on authenticated responses

How every finding is scored and explained

Running the checks is half the product — turning results into something you can act on is the other half.

📊

Severity scoring

Every finding is rated critical, high, medium, low, or info, and rolled up into a single score out of 100 so you can track improvement over time.

  • Critical/high/medium/low/info severity on every finding
  • 0–100 score with weighted penalties per severity
  • Score trend chart across every past scan of the same target
🧬

Live CVE references

Where a finding is a known-vulnerable JS library, we look up real CVE IDs from OSV.dev at scan time rather than relying on a hardcoded list that goes stale.

  • Live OSV.dev lookup for vulnerable JS libraries
  • Checks both direct advisory IDs and GHSA aliases
  • Falls back gracefully — no CVE claimed if OSV.dev is unreachable
🛠️

Copy-pasteable remediation

Every finding type ships with specific fix instructions — config snippets for nginx, Apache, Next.js, and Azure Static Web Apps where relevant, not generic advice.

  • Per-finding Markdown remediation with real config snippets
  • Automated PRs available — findings become an actual pull request with a SECURITY-FIXES.md
  • AI-tailored guidance available on request for your specific detected stack
🔁

Scan-to-scan comparison

Every finding carries a stable identity, so re-scanning the same target shows exactly what's new and what's been fixed — not just a fresh, unrelated list.

  • New vs. fixed vs. unchanged, compared against your last scan
  • Shareable, read-only report links for clients or auditors
  • Exportable PDF reports

How we avoid false positives

The single biggest failure mode for this kind of scanning is a catch-all site that returns 200 for every URL — naively probed, that looks like every sensitive file and every admin panel exists. Here's specifically what stops that.

🧪

Known-404 baseline first

Before probing anything real, every path-probing check fingerprints the site root and a random, guaranteed-nonexistent URL. If that random URL returns 200, the site serves a catch-all — and every subsequent probe gets compared against that baseline, not treated as a finding on its own.

  • Shared across every path-probing check (src/lib/scanners/httpProbe.ts) — one proven implementation, not a copy per scanner
  • ETag / Content-Length compared against the site root as a first, cheap signal
🎭

Path-masked body comparison

Catch-all shells often echo the requested URL back into the page (a router, a canonical link, an error message) — which would otherwise make every probed path look like a different document, and can accidentally satisfy a content check by pure coincidence. The probed path is masked out of both bodies before they're ever compared.

  • Prefix/suffix similarity match on the masked bodies — ≥85% shared content counts as "the same page"
  • Applied identically whether the probe is for a leaked .env file or an open directory listing

Content assertions, not just status codes

A 200 response alone is never enough to call something exposed. Each check asserts the body actually looks like what it claims to have found.

  • A .env "hit" must match a real KEY=value assignment pattern, not just any 200
  • A directory listing must show both an "Index of /..." title and a Parent Directory link — a page that merely loads at /uploads/ (an upload form, say) doesn't count
  • A .htpasswd "hit" must match a real password-hash line format
🎯

Scoped to evidence we actually have

Every check only reports what it can back up — no guessing at what "might" be there.

  • Cloud misconfig only tests buckets the target's own page source references — never guesses bucket names against infrastructure the customer doesn't own
  • CVE references come from a live OSV.dev lookup against the exact detected version — no CVE claimed if the lookup fails or nothing matches
  • CMS deep scans (WordPress/Joomla/Drupal) only run once fingerprinting has actually detected that CMS

What this can't detect

Automated scanning is genuinely good at what's listed above, and genuinely bad at everything below. Worth knowing before you treat a clean scan as a clean bill of health.

  • Business logic flaws — price manipulation, privilege escalation through a legitimate workflow, coupon/quantity abuse. These require understanding what the application is supposed to do, which no automated scan can infer.
  • Deep authenticated testing — every scan here is unauthenticated (black-box against the public site) by default. Connecting a session cookie or Basic Auth credential (Agency plan) re-runs header/cookie/CSP/CORS checks against the logged-in page, but that's a narrow recheck, not a crawl behind login. Access-control bugs that only show up once you're logged in as one user trying to reach another user's data (IDOR), and multi-step auth flows (OAuth, MFA), aren't covered.
  • Zero-days and unknown vulnerabilities — nuclei and the fingerprinting checks match against known template/CVE databases. Anything not yet publicly known or catalogued won't be flagged.
  • DKIM on a custom selector — a DKIM key lives at a selector name chosen freely by whoever set it up, and it cannot be discovered from DNS. We probe the defaults the major providers use, so finding a key is real evidence, but not finding one isn't proof of absence. We report that case as informational, never as “DKIM missing”.
  • Real active scanning, most of the time — nmap/nuclei/sqlmap/XSSer/commix/a real ZAP active scan only run on the scheduled monitoring path, where domain ownership has already been verified. An on-demand dashboard scan is passive/read-only checks only.
  • Physical, social, and process risk — phishing susceptibility, insider threats, physical access controls, offline backup hygiene. None of that is visible from the outside of a website.

For the things on this list, see manual penetration testing — a human tester, not a scanner, is what actually finds these.

// ready?

See it run against your own site

Free scan, one-page report in 24 hours, no commitment.

Run a free scan