Every day, thousands of websites are compromised. In the overwhelming majority of cases the culprit is not a Hollywood-grade exploit. It is an outdated or poorly written plugin. WordPress did not invent that risk, but its architecture makes the consequences worse than they need to be: on a classic install, a broken contact form and your database share the same keys.
This is the third article in our series on EmDash, Cloudflare's open-source CMS (content management system). The first asked whether it is a credible WordPress alternative. This one looks at the part that matters most to a security team: what actually happens when a plugin gets breached, and why EmDash's answer, isolating every extension instead of trusting it, is a real change rather than a marketing line.
One caveat up front, because it shapes everything that follows: EmDash is an early developer preview (version 0.1.0). What we describe here is an architecture, not a battle record. The model is sound. The mileage is not there yet.
The monolith vulnerability: why one WordPress plugin can own everything
To see why EmDash matters, you have to be precise about the weakness it targets. This is not the vague complaint that "WordPress is insecure". It comes down to one specific structural choice.
Shared execution, shared privileges
On a standard WordPress install, the core, the database, and every plugin run inside the same execution space, under the same operating-system user and the same database credentials. A plugin is not a guest with a limited pass. It is a full tenant. The contact form you installed for a single page can, at the architecture level, read every row of your users table, because nothing tells it that it cannot. Privilege is shared by default.
That design made sense in the early 2000s, when a site was a handful of trusted files. It ages badly once a typical site carries twenty or thirty third-party plugins from twenty or thirty different authors.
From a contact form to a compromised server
Here is the chain a security team has watched play out hundreds of times. A plugin ships with a SQL injection flaw (a bug that lets an attacker smuggle their own commands into a database query through an input field). Because the plugin already holds the site's database credentials, the attacker now reads or rewrites any table. If the same plugin can also write files, that often escalates to remote code execution (RCE, running the attacker's own code on the server). At that point the attacker inherits every shared privilege: dump the users table, modify core files, inject malicious scripts into pages served to real visitors, and plant a backdoor for later.
Abandoned plugins make it worse. Code that no longer receives security patches, but still runs with full access, is a standing invitation.
Patchstack's State of WordPress Security 2025 puts a number on where the danger actually lives: across 2025, 91% of disclosed WordPress vulnerabilities were found in third-party plugins and themes rather than in the core, after 96% the year before. The core is not the soft target. The extensions bolted onto it are.
On WordPress, the blast radius of any single plugin is the entire site.
V8 isolates: how EmDash sandboxes every plugin
EmDash runs every plugin inside a Cloudflare V8 isolate, a lightweight sandbox that gives each extension its own sealed slice of memory. Same idea as the monolith, inverted: instead of one shared space, many sealed ones.
What a V8 isolate actually is
V8 is the JavaScript engine Google built for Chrome. An isolate is the mechanism V8 uses to stop one browser tab from reading another tab's memory. Cloudflare reused that mechanism across its network: rather than give each workload its own container or virtual machine (heavy, and slow to start), it runs many isolates inside a single process, each one walled off from the rest. Cloudflare documented the approach in its engineering post, "Cloud computing without containers".
The practical contrast is stark. A container boots in hundreds of milliseconds and carries a small operating system with it. An isolate starts in single-digit milliseconds and carries almost nothing. That is why there is effectively no cold start (the start-up delay familiar from other serverless platforms), and it is why running every plugin in its own sandbox is affordable rather than absurd.
What the isolation prevents, concretely
In EmDash, a compromised plugin is trapped inside its isolate. It cannot read the memory of the CMS core. It cannot see the isolate next door. It has no ambient access to the database or the file system. The very SQL injection that owns a WordPress server hits a wall here: there is no shared database handle to hijack and no server file system to write to. The flaw still exists in the plugin, but its reach stops at the edge of the sandbox.
Isolation does not make a plugin bug-free. It makes a plugin bug survivable.
Permission manifests: capability-based security, like an app on your phone
Sandboxing handles what a plugin can reach in memory. A second layer handles what it is allowed to do at all.
Each EmDash plugin ships a capability-based permission manifest: it must declare, up front, exactly which capabilities it needs, and it receives nothing beyond that list. Capability-based security simply means access is granted per declared capability, not inherited from the surrounding environment.
Declare, or be denied
Like a phone app that has to ask before it touches your camera or your photos, an EmDash plugin states its needs in a manifest file. A simplified example:
{
"name": "Contact Form Pro",
"permissions": {
"content": "read",
"email": "send",
"network": ["api.sendgrid.com"],
"database": false,
"storage": false
}
}A plugin that asks only to read content, send email, and reach a single outbound host cannot query D1 (Cloudflare's SQL database), cannot touch R2 (Cloudflare's object storage for media), and cannot open a connection to anywhere else. Anything not declared is denied. (The exact capability vocabulary is defined by EmDash; treat the keys above as illustrative of the model, not as a fixed API.)
What the runtime does when a plugin steps out of line
The check is not a guideline the plugin is asked to respect. It is enforced by the Cloudflare Workers runtime, below the plugin, not by the plugin's own good behaviour. If an extension whose manifest says "database": false tries to query D1 anyway, the runtime refuses the call. A plugin cannot grant itself a capability it never declared, because the decision lives in the platform, where the plugin cannot reach it. This is least privilege (each component gets only the access it genuinely needs) enforced by architecture rather than by a policy document nobody rereads.
A permission you never granted is an attack you never have to detect.
Case study: migrating WordPress to Cloudflare EmDash
We did not read about this model. We run on it.
brixio.io was rebuilt off WordPress onto EmDash, Astro and Cloudflare, every legacy URL preserved and existing rankings carried through. We have also shipped custom bot defences written entirely on Workers for a client in aviation.
What sandboxing does not fix
Honesty serves the reader better than a clean story here.
EmDash is a v0.1.0 developer preview. The security model above is an architecture, not a track record: it has not been hardened by twenty years of public attack the way WordPress, for better and worse, has. A sound design and a proven one are not the same thing.
Sandboxing also does not retire the rest of a security programme. An isolate contains a compromised plugin, but it does not vet what a legitimate plugin does within its own remit, and it replaces neither authentication, nor secrets management, nor monitoring. Availability is a different question again: running on Cloudflare's network places a site behind the same edge that absorbs large distributed denial-of-service (DDoS) attacks, where traffic is filtered before it reaches your code, but defending availability under real, sustained load is its own discipline. We cover that side in our Cloudflare bot management production guide.
Architecture narrows the attack surface. It does not retire the security team.
Securing the web by architecture, not by vigilance
WordPress security rests on trust plus maintenance: trust that thousands of third-party developers wrote safe code, and the daily discipline of patching for the times they did not. EmDash starts from the opposite assumption, that any plugin may be hostile, and contains it by design: a sealed V8 isolate, a declared set of permissions, a deny-by-default runtime.
The maturity is not there yet. The model is. For a team building today, security by architecture is a steadier foundation than security by vigilance, because it keeps working on the day everyone is too busy to apply the patch. And when that team needs custom features built and operated on the stack, that is our custom application development.
Keep going in this series
- Where it started: why EmDash reads as a credible modern alternative to WordPress, and how the Cloudflare and Astro stack fits together. See Has WordPress finally met its match?
- Performance and cost: how the same architecture targets near-zero hosting bills and instant load times. Read Cloudflare Workers vs AWS Lambda: the serverless cost model. (Article 2)
Frequently asked questions
It is the structural weakness behind most WordPress breaches. On a standard install the core, the database, and every plugin run in the same execution space with the same access rights. A plugin therefore holds the same database and server privileges as the site itself, so a single compromised or abandoned plugin can be used to read the whole database, alter core files, or take over the server.
A V8 isolate is a lightweight sandbox from the JavaScript engine Google built for Chrome, originally used to keep browser tabs from reading each other's memory. Cloudflare runs each Workers workload in its own isolate, walled off from the others, which starts in milliseconds and avoids the cold-start delay of container-based serverless. EmDash uses one isolate per plugin.
Each EmDash plugin declares the capabilities it needs in a manifest, for example reading content or sending email, and receives nothing else. The Cloudflare Workers runtime enforces the manifest: if a plugin tries to use a capability it did not declare, such as database access, the call is refused. The default is deny, so a plugin cannot reach data it never asked for.
Architecturally its plugin model is stronger, because isolation and capability-based permissions contain a compromised extension instead of letting it reach the whole site. In practice EmDash is a v0.1.0 developer preview without WordPress's years of hardening, so for a production-critical site today most teams should pilot it rather than fully migrate.
No, those are separate concerns. Sandboxing limits what a compromised plugin can reach; it does not address availability. DDoS protection comes from running on Cloudflare's edge network, which filters and absorbs attack traffic before it reaches your application. See our Cloudflare bot management production guide for that side.


