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.
- HTTPS and certificate expiryNo HTTPS is reported as critical. Where HTTPS is present the certificate is read for issuer, subject and expiry. Already expired, or under 7 days, is critical; under 21 days is a warning, because at that point automatic renewal should already have run.
- TLS versionThe version the server actually agreed to during the handshake. TLS 1.0 and 1.1 are reported as critical. TLS 1.2 is recorded as acceptable, TLS 1.3 as good.
- HSTS strength, not just presenceA missing Strict-Transport-Security header is critical. Where it is present, a max-age below 15552000 seconds (six months) is a warning, a missing includeSubDomains is noted, and the header is tested against the preload requirements: a year or more, includeSubDomains, and preload.
- Content-Security-Policy and framingA missing CSP is critical. A CSP allowing 'unsafe-inline', 'unsafe-eval' or a wildcard default-src is a warning. Framing is checked separately: with neither X-Frame-Options nor a CSP frame-ancestors directive, nothing stops another site loading your pages in an invisible iframe.
- Cookie flags and prefixesRead from the Set-Cookie header your site already sent. Missing HttpOnly or Secure is a warning, missing SameSite is information. The absence of __Host- or __Secure- prefixes is recorded as hardening rather than as a defect.
- Mixed content and Subresource IntegrityHTTP links on an HTTPS page are critical. Cross-origin scripts and stylesheets loaded without an integrity attribute are reported as information; same-host files and inline data: URIs are excluded, so an inlined critical-CSS block is not miscounted as a third-party resource.
- Known-vulnerable JavaScript librariesIdentified from version strings already in the URLs your pages load: AngularJS 1.x (end of life since 31 December 2021), jQuery below 3.5.0 (CVE-2020-11022 and CVE-2020-11023), Lodash below 4.17.21 (CVE-2019-10744), Bootstrap 3.x. Where a filename gives only two version components, the highest release it could mean is the one tested, so a patched install is not flagged. Moment.js is deliberately excluded: it is feature-frozen, not vulnerable.
- Credentials in page sourceAPI key, token, secret and password assignments in markup — minus an exclusion list for credentials designed to ship to the browser: Stripe publishable keys, Shopify storefront access tokens, Algolia search-only keys, GA4 measurement IDs and reCAPTCHA site keys.
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.
- RFC 9116 — security.txt
- HSTS preload requirements
- MDN — Set-Cookie and cookie prefixes
- MDN — Subresource Integrity
- Let's Encrypt — certificate lifetime and renewal
- AngularJS version support status
- CVE-2020-11022 (jQuery)
- CVE-2019-10744 (Lodash)
- Computer Misuse Act 1990
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.