EmDash Plugin Permissions: The Real Danger Isn’t What You Think

EmDash's plugin sandbox is technically sound, but the real vulnerability is your own approval.

By Central
EmDash's permission system relies on user vigilance, not just technical enforcement.
Highlights
  • EmDash runs each plugin in a V8 isolate that physically blocks unauthorized access.
  • The system does not limit how many capabilities a single plugin can request.
  • Self-hosting EmDash on Node.js removes sandbox isolation entirely.

The most dangerous plugin in EmDash isn’t the one that secretly steals your data. It’s the one that asks for everything and gets approved. Cloudflare’s new CMS has a sandbox that physically blocks unauthorized access, but it cannot stop you from granting permission to a plugin that requests too many capabilities. That’s not a technical flaw. It’s a trust problem wearing a security badge.

How EmDash Plugin Permissions Actually Work

EmDash runs every plugin inside its own V8 isolate, a lightweight sandbox powered by Cloudflare’s dynamic workers. The plugin cannot touch your database, your file system, or any other part of the CMS unless you explicitly allow it.

EmDash solved the technical problem of plugin security. It did not solve the social problem of permission hygiene.

Each plugin declares its capabilities in a manifest. A contact form plugin might request read contentcodecodecodecode and send emailcodecodecodecode. That’s it. The runtime enforces the boundary at the hardware level using Linux namespaces, seccomp filters, and memory protection keys.

But here’s the thing: EmDash does not limit how many capabilities a single plugin can request. A plugin could ask for read contentcodecodecodecode, write contentcodecodecodecode, delete contentcodecodecodecode, read userscodecodecodecode, write userscodecodecodecode, send emailcodecodecodecode, make external network requestscodecodecodecode, and manage settingscodecodecodecode. The system will happily let it declare all of those. The question is whether you, the site owner, will approve them.

The Manifest System: What Plugins Can and Cannot Declare

The manifest is a simple JSON-like structure inside the plugin code. Here’s a real example from the EmDash documentation:

“`javascript

definePlugin({

id: ‘my-plugin’,

version: ‘1.0.0’,

capabilities: [‘read:content’, ’email:send’],

hooks: {

‘post:published’: async (context) => {

const email = context.getCapability(’email:send’);

// send email about new post

}

}

})

“`

The plugin cannot access anything outside those declared capabilities. It cannot read user passwords, cannot write to the database, cannot make HTTP requests to external servers. The dynamic worker enforces this at runtime.

But notice: nothing prevents the plugin from listing read:userscodecodecodecode, write:contentcodecodecodecode, network:allcodecodecodecode, and admin:settingscodecodecodecode. The system does not have a “max permissions” cap. It trusts you to evaluate each request.

The Real “Flaw”: User Trust vs. Technical Enforcement

The WordPress ecosystem conditioned millions of users to install plugins without reading what they do. You click “Install Now” and the plugin gets full access to everything. EmDash breaks that pattern. You see a permission dialog before installation.

But will you actually read it? History says no. The same users who clicked “I agree” without reading terms of service will click “Approve” on a plugin that requests delete:allcodecodecodecode because they just want the feature to work right now.

Cloudflare built a technically superior security model. They did not build a user education system. The architecture prevents a plugin from stealing data it hasn’t been granted, but it cannot prevent you from giving that data away.

Could a Plugin Request All Permissions? Yes. So What?

A malicious plugin could request every available capability. If you approve, it has the same practical access as a WordPress plugin. The difference is that in WordPress, that access is implicit and unavoidable. In EmDash, it’s explicit and requires your consent.

This is not a flaw in the sandbox. It’s a feature of the permission model. The question is whether the average EmDash user will treat that permission dialog with the gravity it deserves.

Consider the economics. EmDash’s full sandbox requires Cloudflare’s paid plan at $5/month. The target audience includes developers and small publishers—people who understand technical trade-offs. But as EmDash grows, it will attract less technical users. That’s when the permission model becomes a vector, not a shield.

What Happens When a Plugin Oversteps? Nothing—Unless You Deny It

If a plugin tries to execute code outside its declared capabilities, the runtime throws an error. The plugin fails. Your site continues running. No data is exposed, no files are deleted, no emails are sent to attackers.

But if a plugin declares network:allcodecodecodecode and you approve it, then it can exfiltrate your content to any server. The sandbox did its job by showing you the request. The failure was yours.

This mirrors the App Store model on iOS. Apple can’t stop you from granting location access to a flashlight app. They can only force the app to ask first.

The Harder Problem: Plugin Ecosystems Without Trust Infrastructure

WordPress has 60,000+ plugins. EmDash launched with zero. To build an ecosystem, you need to attract developers. Developers want to monetize. The GPL license in WordPress forces many developers into restrictive licensing. EmDash uses MIT, which allows closed-source plugins.

But closed-source plugins in a sandboxed environment are hard to audit. You cannot inspect the source code to verify it only does what it claims. The permission manifest becomes your only defense. If a plugin requests network:allcodecodecodecode, you have to trust the developer’s intent.

Cloudflare’s solution to this is the 402 payment protocol and the MCP server for AI agents. The idea is that AI can generate plugins on demand, reducing reliance on a marketplace. But AI-generated code is even harder to audit for permission abuse.

Where This Architecture Breaks Down

The sandbox only works on Cloudflare’s runtime. If you self-host EmDash on a Node.js server, plugins run in-process without isolation. The permission model collapses. You get no protection at all.

This is the same lock-in critics have pointed out. The feature that makes EmDash genuinely superior to WordPress requires you to stay inside Cloudflare’s infrastructure. Open source code, proprietary runtime.

The counterintuitive truth: EmDash’s security is strongest when you trust Cloudflare and weakest when you trust yourself. The plugin permission system is a marvel of modern isolation, but it cannot protect you from your own approval.

The Future: Permission Fatigue and the AI Agent Problem

EmDash is built for AI agents. The MCP server allows agents to create plugins and manage content programmatically. An AI agent could request permissions on your behalf. If the agent is compromised, or if you give it overly broad permissions, the sandbox becomes irrelevant.

This is the next frontier. Dynamic workers were originally designed to run AI-generated code safely. EmDash reuses that technology for plugins. But AI agents don’t read permission dialogs. They execute instructions. If an agent is told to “install this plugin and grant all permissions,” it will do exactly that.

The architecture is sound. The human element is not. EmDash solved the technical problem of plugin security. It did not solve the social problem of permission hygiene. That’s the real flaw, and it’s one no sandbox can fix.

Questions answered
  • How does EmDash enforce plugin permissions?EmDash runs each plugin in a V8 isolate sandbox powered by Cloudflare's dynamic workers. The plugin cannot access anything outside its declared capabilities.
  • What is the real flaw in EmDash's plugin security?The real flaw is user trust. EmDash cannot prevent you from approving a plugin that requests too many capabilities.
  • Does EmDash's sandbox work on self-hosted servers?No. If you self-host EmDash on a Node.js server, plugins run in-process without isolation and the permission model collapses.
Share This Article