Security by not having a server: static sites and the patching treadmill
Why a static site on an edge network has no database, no admin login and no plugins to patch, what still needs watching, and how that compares with a plugin-based CMS site. Fully referenced.
Most security advice for a business website is a list of chores. Update the platform. Update the plugins. Protect the login page. Lock down the database. The list is long because the site is a running program with many parts, and each part can go wrong. This post is about a different approach: build a site that does not have most of those parts. It explains what a static site leaves out, what still needs watching, and how the two shapes compare.
The patching treadmill
The clearest picture of the problem comes from Patchstack, a security company that coordinates the disclosure of vulnerabilities in the WordPress ecosystem. Its 2026 report counts what was found in the previous year: “11,334 new vulnerabilities were found in the WordPress ecosystem in 2025”[1]. Almost none of them were in WordPress itself. “91% of new vulnerabilities were found in plugins, and 9% were found in themes”[1], while “There were only 6 vulnerabilities reported in the WordPress core, but these were low priority issues”[1].
A plugin is a package of code added to a content management system to give it a feature: a contact form, a gallery, a booking calendar. Each one runs on the server with the same access as the site itself, and each is maintained by someone else on their own schedule. The report records what happens when that schedule slips: “46% of vulnerabilities were not fixed in time for public disclosure”[1]. Nearly half the time, the flaw was public before the fix was.
WordPress’s own hardening guide is honest about what this means for an owner. It opens with the principle that security “is risk reduction, not risk elimination”[2]. Then it lists the work: “you should always keep up to date with the latest version of WordPress. Older versions of WordPress are not maintained with security updates”[2]. For plugins, “make sure your plugins are always updated. Also, if you are not using a specific plugin, delete it from the system”[2]. It recommends “server-side password protection” for the admin area[2]. None of that advice is wrong. It is a treadmill, and somebody has to stay on it for as long as the site exists.
What a static site does not have
A static site is built in advance. The pages are made into finished HTML, CSS and image files before anyone visits, and those files are copied to an edge network, which is a set of servers spread around the world so that a visitor in Perth is served from somewhere near Perth. This site is deployed that way, to Cloudflare Pages.
The headline “no server” needs one honest footnote. There are servers; they belong to Cloudflare. What matters is what runs on them for this site: a file server handing out pages that were finished before the visit. There is no database, because the content is already in the files. There is no admin login page, because nobody edits the live site; changes are made in the code and the site is rebuilt. There are no plugins, because there is no program on the server for them to plug into.
The OWASP Top 10 is “a standard awareness document for developers and web application security”[3], a ranked list of the ways web applications get broken into. Read against a static site, several of its categories describe doors that do not exist. Authentication failures, for example, are about systems that permit “brute force or other automated, scripted attacks that are not quickly blocked” and “default, weak, or well-known passwords, such as ‘Password1’ or ‘admin’ username with an ‘admin’ password”[4]. A site with no login page has no login to guess. Injection attacks need a server that takes a visitor’s input and runs it against a database; a page that is a file cannot be tricked that way. The whole argument in one sentence: the cheapest vulnerability to fix is the one you never installed.
What still needs watching
A static site is not zero maintenance. It is short-list maintenance. Four things remain.
The few dependencies
The site is built with tools, mainly Astro and React, and those tools are software with their own dependencies. OWASP’s newest category, software supply chain failures, warns that they “are often caused by vulnerabilities or malicious changes in third-party code, tools, or other dependencies that the system relies on”[5], and that the risk is highest when “you do not carefully track the versions of all components that you use”[5].
Two things make this manageable. First, these tools run at build time, on the machine that makes the files, not on the live site. A flaw in a build tool is worth fixing, but it is not a door a visitor can walk through. Second, every version is written down in the code, and the repository is watched. GitHub’s Dependabot “help[s] you find and fix vulnerable dependencies before they become security risks” and “sends alerts when: A new vulnerability is added to the GitHub Advisory Database” or when the list of packages changes[6]. That is the treadmill again, but a short one, and it is ours to run, not yours.
The form endpoint
One piece of code on this site does accept input from strangers: the contact form. It runs as a Cloudflare Pages Function, which lets us “deploy server-side code to enable dynamic functionality without running a dedicated server”[7]. It checks the submission and sends the email, and it is the one place the full set of precautions applies. Submissions carry a Cloudflare Turnstile token, checked on the server, not just in the browser, because as Cloudflare’s documentation puts it, “Tokens can be forged. An attacker can submit any string to your form endpoint without completing a challenge”[8]. Tokens are also “single-use”, so a captured one cannot be replayed[8]. A honeypot field catches the simplest bots before that.
DNS and domain accounts
The keys to any website, static or not, are the accounts that control the domain name and its DNS records. Whoever holds those can point your address anywhere. No site security helps if the registrar password is weak, and OWASP’s advice for any login applies: no “default, weak, or well-known passwords”[4]. We set up DNS and SSL at launch, but the registrar account stays yours, and it deserves a long unique password and every second factor the registrar offers.
Security headers
The last item is a set of instructions the site sends to the browser with every page. OWASP lists their absence as a misconfiguration: “The server does not send security headers or directives, or they are not set to secure values”[9]. On Cloudflare Pages the default headers “can be overridden, removed, or added to, by creating a plain text file called _headers”[10], and this site has one. It sends five headers on every page:
- Strict-Transport-Security, which “informs browsers that the host should only be accessed using HTTPS, and that any future attempts to access it using HTTP should automatically be upgraded to HTTPS”[11].
- X-Frame-Options, which tells the browser whether the page may be shown inside another site’s frame; sites use it “to avoid clickjacking attacks”[12], where a hidden copy of your page is placed under a visitor’s cursor.
- X-Content-Type-Options, Referrer-Policy and Permissions-Policy, which stop the browser guessing file types, limit what your visitors’ browsers tell other sites about where they came from, and switch off the camera, microphone and location features the site does not use.
Each is one line in a file that ships with the build.
The comparison
| Attack surface | Plugin CMS site | Static edge site |
|---|---|---|
| Admin login page | Public, always on, a brute-force target | None |
| Database | Yes, holding all content and users | None |
| Plugins on the live server | Typically many; 91% of 2025’s WordPress vulnerabilities were in plugins[1] | None |
| Server-side code | The whole CMS, running for every request | One form handler |
| Software to keep updated | CMS, plugins, themes, language runtime, server | Build tools, updated in the code with Dependabot alerts[6] |
| Contact form | A plugin with server access | A Pages Function with Turnstile and a honeypot |
| Security headers | Depends on host or another plugin | Five lines in _headers[10] |
| Domain and DNS accounts | Yours to protect | Yours to protect |
What this does not solve
Two limits are worth saying plainly. A static site is the wrong shape for some businesses: if you need customer accounts, a shopping cart or a database of anything, you need a server-side application, and it will carry the risks in the left-hand column no matter who builds it. We do not build those, and we will say so at the brief stage.
And the accounts around the site matter more than the site. A phished registrar login beats any architecture. The hardening guide’s phrase holds for every site ever built: risk reduction, not risk elimination[2]. The point of a static build is that the list of risks left to reduce is short enough to finish.
What you can do next
If you already have a site, look for a /wp-admin/ or /login page: if it exists, it is a door. Then paste your address into a header checker and see which of the five headers above come back. Our own build is measured on the home page, and the React and islands posts explain the rest of the stack.
If you are planning a build and want to know how much of your site could be static, the brief builder takes three minutes and the answer comes back with a fixed price.
Reference list
All sources accessed 18 August 2026.
- Patchstack (2026) State of WordPress Security in 2026. Patchstack whitepaper, data updated 25 February 2026. https://patchstack.com/whitepaper/state-of-wordpress-security-in-2026/
- WordPress (n.d.) Hardening WordPress. WordPress Developer Resources, Advanced Administration Handbook. https://developer.wordpress.org/advanced-administration/security/hardening/
- OWASP Foundation (n.d.) OWASP Top Ten. https://owasp.org/www-project-top-ten/
- OWASP Foundation (2025) A07:2025 Authentication Failures, in OWASP Top 10:2025. https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/
- OWASP Foundation (2025) A03:2025 Software Supply Chain Failures, in OWASP Top 10:2025. https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/
- GitHub (n.d.) About Dependabot alerts. GitHub Docs. https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts
- Cloudflare (n.d.) Pages Functions. Cloudflare Docs. https://developers.cloudflare.com/pages/functions/
- Cloudflare (n.d.) Turnstile: Server-side validation. Cloudflare Docs. https://developers.cloudflare.com/turnstile/get-started/server-side-validation/
- OWASP Foundation (2025) A02:2025 Security Misconfiguration, in OWASP Top 10:2025. https://owasp.org/Top10/2025/A02_2025-Security_Misconfiguration/
- Cloudflare (n.d.) Pages: Headers. Cloudflare Docs. https://developers.cloudflare.com/pages/configuration/headers/
- Mozilla (n.d.) Strict-Transport-Security header. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security
- Mozilla (n.d.) X-Frame-Options header. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options