Skip to content

LiveSeptember 23, 2026 · one session

WP Front Door

A five-second, no-login check of what a WordPress site leaks, caches and should fix first.

I built WP Front Door to answer the first question about any WordPress site in five seconds: what does its front door give away, is it really cached, and what should be fixed first. It reads only what a visitor's browser would get, stores nothing, and refuses to fetch anything on a private network.

distinct checks a report can raise
22
tests: fixtures, a fake network, a local server and the limits
27
runtime dependencies besides Next.js and React
0
address checks per hop, one inside the socket
2
timeout per request
8 s
body cap per fetch
1.5 MB
redirect hops at most
5
records stored
0

Architecture

Five parts, without a database.

My role: Product owner and developer. I set the brief (useful, current and free to run) and shipped it to production, with Claude Code as my AI pair programmer.

  • src/lib/target.ts

    The address rules and the pre-check: http(s), standard ports, without private ranges.

  • src/lib/transport.ts

    node:http with a guarded DNS lookup, a fresh socket per request, gzip and brotli, a body cap.

  • src/lib/fetch.ts

    Redirects followed by hand, every hop checked again; failures explained in plain words.

  • src/lib/check.ts

    The four probes, the analysis and the scores; a pure function the fixtures test.

  • src/app

    next/form, a streamed loading state, the server-rendered report and the JSON endpoint.

  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • Vitest
  • Vercel
  • Jev (TypeSafe AI)

What it reads

Twenty-two findings from what a visitor's browser would get

Paste an address and the report groups what it found into what the site leaks, what it sends, how it caches, how heavy the page is and what runs on it. Every finding says what was seen and how to fix it; the five that matter most come first.

What it leaks

  • The WordPress version in the generator tag or in readme.html
  • Account names listed by /wp-json/wp/v2/users to anonymous requests
  • XML-RPC answering as a live endpoint

What it sends

  • HTTPS on the final address, and HSTS
  • X-Content-Type-Options, framing protection, Referrer-Policy, a content security policy

Caching and speed

  • Whether this request came from a page cache or CDN: Cloudflare, LiteSpeed, Vercel, Kinsta, WP Engine, Sucuri and the caching plugins' signatures
  • The Cache-Control policy, the time to first byte on the final hop, and how many redirects came first

Page weight and footprint

  • Document size, scripts in the head, stylesheets, images without dimensions, third-party script hosts
  • The theme and every plugin that loads assets on the page

Built to be run by strangers

A checker that cannot be turned into a scanner

A tool that fetches whatever address it is given is a server-side request forgery waiting to happen. The rules are small and tested.

Addresses

  • Only http and https on the standard ports; no credentials in the address; no .local hosts
  • Every hostname is resolved before it is fetched and refused if any answer is a private, loopback, link-local or special range, IPv4 or IPv6
  • The same check runs again inside the socket's own DNS lookup, so a name cannot resolve public for the check and private for the connection (DNS rebinding)

Fetching

  • Redirects are followed by hand, at most five, each hop checked again, so a redirect cannot lead inside a network
  • Eight seconds per request and 1.5 MB per decompressed body; ten checks a minute per address and at most twenty checks of one site in ten minutes, whoever asks, on each server instance
  • Nothing is written anywhere: every report is generated fresh from the responses, and the JSON endpoint says so with no-store

One typed question

What kind of site is this?

The same finding matters differently to a store and to a company site: a store lives on cached, fast pages; a small business site on not leaking its login names. With a TypeSafe key, Jev answers one choice question about the page's title, description and opening text, in a few hundred milliseconds at most, and the fix-first list is ordered for that kind of site. Without the key the report is the same, unordered by kind.

Why Jev and not a chat model

  • It answers a typed question with a choice and a probability; nothing is generated, nothing can be made up
  • A few hundred input tokens per check at $0.042 per million: effectively free, and off without the key
  • One request per check under a daily budget, and a page with text written to steer AI readers is never sent to Jev; the report says so

Tests and delivery

Fixtures for the analysis, a fake network for the fetching

The analysis is a pure function of what was fetched, so it is tested with HTML fixtures: a bare install with every leak, a well-set-up site, a page that is not WordPress at all. The fetching is tested with an injected fetch and resolver, and the transport against a real local server: decompression, the body cap, redirects handed back, and a name that resolves inside the network refused at connection time.

Checks before shipping

  • Vitest, TypeScript strict, ESLint and a production build, on every push through GitHub Actions
  • Real checks of wordpress.org and woocommerce.com, and the refusals (127.0.0.1, localhost, 169.254.169.254, a decimal-encoded loopback, a non-standard port), before the first deploy

Hosting

  • Vercel, from a private GitHub repository; no database and no paid service

Growth

Skills I sharpened.

Next.js 16
App Router, next/form with a loading state, a server-rendered report, a route handler, Tailwind CSS 4.
Security
SSRF prevention: private ranges refused before the request and inside the socket's DNS lookup, manual redirects, timeouts, caps, rate limiting.
WordPress
What a site exposes from outside: REST user listing, XML-RPC, version leaks, caching layers, plugin footprint.
Testing
Vitest with HTML fixtures and an injected fetch and resolver.
AI
Jev (TypeSafe AI) classifying the site kind to order the fixes; optional, typed, cheap.