WordPress EngineeringOpen-source reference

Website Health Report

A free, passive website check built as a WordPress block theme and plugin, a Laravel scanner and a signed n8n pipeline

By Lotfi Otmanine

Client
Own project, free public tool
Engagement
Portfolio build, open source
Stack
WordPress 7.1Block themeCustom pluginAction SchedulerLaravel 13n8nGoogle SheetsBrevoCloudflare TurnstileWordfenceDockerCoolify

Key result

Passive

no port scans, no credential tests

01

Context

The Website Health Report is a free tool at health.oldev.site. A visitor enters a website they own and gets a scored report on security headers, TLS, DNS and email authentication, performance and SEO basics. The checks are passive: they read public pages and DNS records, and never scan ports, test credentials or exploit anything.

The report opens at a private, unguessable link. A PDF copy can be sent by email with the visitor's consent, a magic-link dashboard keeps scan history, rescans and comparisons, and the visitor can delete their data at any time. Data is removed after 30 days.

02

The Challenge

  • Fetching untrusted websites from a server is a classic SSRF risk: a submitted address must never reach a private network.
  • Scans take time and call outside services, so they cannot run inside a page request.
  • WordPress, the scanner and n8n pass results to each other, and none of them may forge or replay a result.
  • A free public form invites abuse: bots, floods and repeated scans of the same domain.
  • Privacy by default: consent before any email, a short retention window and a real delete button.

03

Scope and Approach

Intake

A URL form with Cloudflare Turnstile verified on the server and a required ownership consent box. Per-IP limits and a per-domain cooldown apply before anything is queued.

Queue and pipeline

The custom plugin, oldev-health-report, stores scans in custom tables and hands each one to an Action Scheduler job, which sends an HMAC-signed message to the n8n scan pipeline.

Passive checks

A Laravel 13 scanner service runs the checks against the submitted site. n8n adds performance data from PageSpeed Insights and email authentication from DNS.

Scoring and reports

The plugin scores each category and renders the report at an unguessable link, in a custom block theme, oldev-health, that follows the oldev.site design system in light and dark. An optional AI summary has a rule-based fallback.

Delivery

Lead rows and report emails go through a signed outbox to n8n, which stores leads in Google Sheets and sends report emails through Brevo.

Operations

An admin screen shows queue health, usage and the abuse log. A retention job deletes data after 30 days, Wordfence runs as the firewall, and everything ships as Docker images on a self-hosted Coolify server.

04

Architecture flow

Visitor submits a site
Turnstile and ownership consent
WordPress plugin
limits, custom tables, Action Scheduler
n8n scan pipeline
HMAC-signed messages
Laravel scanner
passive checks only
Scored report
private, unguessable link
PDF requested?
with consent
yes
PDF by email
Brevo, via n8n
no
Report link only
Magic-link dashboard
history, rescans, comparisons

05

Technical Deep Dive

An SSRF guard on every request

Every A and AAAA record is resolved first, and one private or reserved address rejects the host. The connection is pinned to the checked address, redirects are followed by hand with every hop checked again, only ports 80 and 443 are allowed, and time and size limits apply.

Signed messages between systems

Every message is signed with HMAC-SHA256 over its raw bytes, compared in constant time, accepted only inside a 300-second window and recorded in a nonce ledger. A finished scan can never be overwritten.

An outbox for leads

Lead events wait in an outbox table until n8n confirms them, and only the row id goes through the queue. A failed delivery is retried instead of lost.

An AI summary the scanned page cannot steer

The optional summary prompt holds only check results this code generated, never text from the scanned page. When the AI call is unavailable, a rule-based summary is used instead.

06

Engineering Decisions

WordPress for the product, Laravel for the risky part

Outbound requests to untrusted hosts run in a separate scanner service, away from the WordPress site that holds the reports and the leads.

Delivery behind a webhook

Email, sheet and CRM delivery go through the n8n webhook, so any of them can be swapped without touching WordPress. New checks are added in the scanner service and scored in the plugin.

Hard caps on a free tool

Per-IP limits, a per-domain cooldown and global daily caps on scans, emails and AI calls keep a public form from becoming a cost or an abuse channel.

07

Results

  • A free public tool that checks security headers, TLS, DNS and email authentication, performance and SEO basics without intrusive scanning.
  • Reports at private links, an optional PDF by email with consent, a magic-link dashboard with rescans and comparisons, delete-my-data at any time and removal after 30 days.
  • PHPUnit suites for the WordPress plugin and the Laravel scanner, PHPCS and PHPStan, and Playwright browser tests at desktop and phone width.
  • Secret scanning on every push to the public repository.
  • Built to extend: new checks go into the scanner and are scored in the plugin, and delivery can be changed in n8n without touching WordPress.
  • Performance scores can be missing when the free PageSpeed quota is reached.

Have a site that needs this kind of care?

Tell me what is breaking or what you need built. I will reply with how I would approach it and what I would check first.

Custom quote within 24 hours

Chat on WhatsApp