Security

The security checks we run, and the ones we don't

A security check on a small business website is not a penetration test. It reads what your server already tells every visitor who arrives: the certificate, the response headers, the DNS records, and the scripts your pages ask the browser to load.

What the check reads

Your website answers every visitor with more than a page. It also sends a certificate, a set of response headers, and a list of other files for the browser to fetch. Almost everything in a security audit is already in that answer. We read it from the outside, the way any browser does. Nothing is installed and no access to your hosting is needed.

When something cannot be read, it is recorded as unmeasured, with the reason. A DNS lookup that did not complete is written up as exactly that, never as "the record is missing". A check that failed to run is a fact about our connection, not a defect on your site, and treating the two as the same thing is how free scanners produce long red lists that mean nothing.

The certificate and the connection

If there is no HTTPS at all, that is the most expensive finding on the page: browsers label the site "Not Secure" before anyone reads a word. Where HTTPS is present, the handshake is completed and the certificate read — who issued it, when it expires, and which version of TLS the server agreed to. TLS 1.0 and 1.1 are reported as critical, because modern browsers and payment processors reject them.

Expiry thresholds are deliberately tight. Under 21 days is a warning; under 7 days, or already expired, is critical. An earlier version of the check warned at anything under 90 days and fired constantly on healthy sites — 69, 73, 78 and 83 days all triggered it, and none of them needed action. A Let's Encrypt certificate lives 90 days and renews itself at around 30 days remaining, so "expiring soon" only means something once renewal should already have run and has not.

Headers, cookies and leaks

Headers are the instructions your server gives a browser about how to treat your pages. A missing Content-Security-Policy or HSTS header is reported as critical. A policy that is present but permits 'unsafe-inline', 'unsafe-eval' or a wildcard source is a warning, because a policy with a hole in it reads as protection and is not. HSTS is judged on strength as well as presence: a max-age under six months is a warning, and the header is checked against the published preload requirements.

Cookies are read from the Set-Cookie header your site already sent. Missing HttpOnly or Secure is a warning; missing SameSite is information. Mixed content — plain HTTP links on an HTTPS page — is critical, because browsers block or warn on it and something visibly stops working. Credentials left in page source are flagged too, minus an exclusion list for the ones that are public by design. Telling a client to remove a Stripe publishable key is wrong advice, and their own developer disproves it in seconds.

Hardening: shown, never counted against you

Some findings are true, actionable, and shared by very nearly every small business site: no CAA record naming which certificate authorities may issue for the domain, no /.well-known/security.txt for reporting a problem, no cross-origin isolation headers, and cookies without the __Host- or __Secure- prefixes. These are listed separately as hardening — shown in full, with the reason each one matters, but not scored and not counted as issues.

The reason is arithmetic. They fired together on every audit, holding the security score at 87 for a site with otherwise faultless configuration and inflating the issue count printed on the front of the report. A number that rises on every site tells you nothing about yours. The same applies to the summary count of security headers: each missing header already has its own line, so the roll-up is shown as context and carries no score of its own.

What we will not do without written permission

There is no probing. No requests for files your pages never linked to, no forged headers, no parameters fed in to see what breaks, no vulnerability scanner aimed at your server. Those checks exist in the tool and are inert by default. They run only with written authorisation for that specific domain, and authorisation is per site, not per customer.

Part of the reason is legal: unsolicited probing is an offence under the UK Computer Misuse Act, the US CFAA and Pakistan's PECA. Part of it is practical — a check that reads only what your server volunteers cannot break anything, and appears in your logs as an ordinary visit. If you want the other kind, the scope goes in writing first.

What the engine checks here

Each of these is a rule in the code, not a category heading.

Questions

Is this a penetration test?

No. A penetration test sends your server traffic designed to find out what breaks. This reads what your server already sends to every visitor. The probing checks exist in the tool but stay switched off unless there is written authorisation for that specific domain, and that is separate work with a scope agreed in advance.

Do you need access to my site or hosting?

No. Every check here runs from the outside, using what a browser already receives. Nothing is installed and nothing on your site changes. The one unlinked address we fetch is /.well-known/security.txt, which exists in the standard precisely so that anyone can fetch it.

My site is a brochure with no logins or payments. Does any of this matter?

Some of it does not, and the report says so rather than padding the list. What matters on a brochure site is the part visitors see: a missing or expired certificate puts a full-page warning in front of them, and mixed content makes browsers block parts of the page. Header hardening on a site with no accounts is genuinely lower priority, and it is ranked that way.

Sources

Public and checkable. Nothing here rests on a number we cannot point at.

This is one of fifteen categories. You can read a real report this engine produced on this very site — including the findings it raised against us — or ask for an audit of yours.