SYSTEM NOTICE

Auto translation by AI. Be sure, accuracy, nuances and authorial intent may not be fully reflected.
見出し画像

Holes that Cloudflare WAF cannot plug, and the option of EmDash (WordPress alternative)

In April 2026, it was discovered that over 30 WordPress plugins distributed by EssentialPlugin had been compromised with backdoors. The impact is estimated to affect over 400,000 installations (TechCrunch report, April 14, 2026). According to Patchstack, the plugin suite was acquired via Flippa around August-September 2025, and backdoors were embedded shortly thereafter. Activation occurred on April 5, and discovery on April 7. This means updates continued to be distributed as legitimate plugins for over half a year.

In June 2026, the ShapedPlugin incident was reported. Attackers infiltrated the vendor's build and distribution pipeline, injecting malicious code into paid plugins distributed through legitimate license update channels. The affected products include three items such as Product Slider Pro for WooCommerce (version 3.5.4 and earlier), and CVE-2026-49777 has been assigned a CVSS score of 10.0.

In both cases, the WAF was not broken. The intrusion occurred through the very path used when clicking "Update" in the management dashboard.

The scope protected by Cloudflare WAF

I will state this first so as not to underestimate WAFs. Cloudflare's Free Managed Ruleset is automatically applied to all plans, including Free, and includes rules for responding to "very common WordPress known exploits," alongside Log4j and Shellshock. Each rule is tagged by technical stack, and guidance is provided on operating with the `wordpress` tag rules enabled.

Cloudflare's official support documentation outlines a three-stage approach to protecting WordPress. Use Managed Rulesets and the OWASP ruleset to stop XSS/SQLi. Place a skip rule on `/wp-admin/` and restrict access by IP, ASN, Cookie, etc. Beyond that, implement management dashboard access restrictions via Zero Trust Access, mTLS, and login brute-force countermeasures using Rate Limiting.

Doing this significantly reduces known attacks coming from the outside. It is a perfectly reasonable starting point.

Syntax is visible, but meaning is not

A WAF inspects the syntax of a request, but it does not know how the application treats it internally. This is why it struggles with post-authentication vulnerabilities, privilege escalation, and flaws in business logic. Attacks like IDOR, where the request is syntactically valid and contains no payload, pass through, and zero-day attacks without signatures are not stopped either.

The two cases mentioned at the beginning are one step further outside that scope. A WAF looks at requests entering the site. Plugin updates are something the site fetches itself and executes internally. They never cross the inspection line in the first place. Once they start moving, it is not an attack, but the site's own legitimate operation.

This is where WordPress plugins are powerful. They directly touch the site's database and file system. In Cloudflare's words, "There is no isolation." The moment you install one, you have handed over almost everything.

The percentage decreased, but the number of cases increased

According to Patchstack's "State of WordPress Security in 2026" (published February 25, 2026, with 2025 data), there were 11,334 new vulnerabilities in 2025, a 42% increase from 2024, with 91% originating from plugins. The previous year's version (March 2025, with 2024 data) reported 7,966 cases, with 96% originating from plugins. The "96%" figure cited by the EmDash official blog refers to this number.

Although the percentage decreased, the number of cases increased by 1.4 times. What is more striking is the timeline: the median time from vulnerability disclosure to large-scale exploitation is 5 hours. Approximately 50% of high-risk vulnerabilities are exploited within 24 hours. The operational practice of "updating when you notice" does not align with that 5-hour window.

What EmDash changed is how permissions are held

Cloudflare announced EmDash on April 1, 2026. Given the date, one might suspect a joke, but development has continued, and v0.26.0 was released on July 1, 2026. It is an MIT-licensed CMS written in TypeScript, based on Astro 6.0, and running on Cloudflare Workers, positioned as "the spiritual successor to WordPress." I have not touched it yet, so the following is based on reading the official documentation.

The key is how plugins are executed. EmDash plugins run in a Worker sandbox using a Dynamic Worker Loader—that is, inside a V8 isolate—and each declares a capability manifest. The declaration is made in `emdash-plugin.jsonc` (as of July 2026 notation).

{
  "slug": "plugin-hello",
  "capabilities": ["content:read", "network:request"],
  "allowedHosts": ["api.example.com"]
}

What is interesting is that it is not designed to block via permission checks. The docs state: "Calling a method on an undeclared capability isn't possible — there's no object there." Only `ctx.content` or `ctx.http` corresponding to the declared capability are injected, and for those not declared, the object to call simply does not exist.

The sandbox version cannot see environment variables or the file system, and direct calls to `fetch()` are blocked by the runner. Themes are also said to "can never perform database operations." Distribution is only via marketplace.emdashcms.com, and arbitrary zip files are not supported. A permission consent dialog is presented before installation, and Passkey is the default for authentication.

If we apply the methods mentioned at the beginning to this, even if one tried to rewrite something equivalent to `wp-config.php`, the file system is invisible. Even if one tried to connect to a C2, if `network:request` was not declared, `ctx.http` would not exist.

An honest disclaimer

However, I cannot write that "plugins are safe with EmDash." The official documentation itself admits its limitations (all information below is as of July 2026).

The biggest issue is money. The README states that running sandbox plugins depends on Dynamic Workers, which is only available on paid accounts. The options presented are to either upgrade to Workers Paid, starting at $5/month, or to comment out the `worker_loaders` block in `wrangler.jsonc` to disable plugin functionality. This is the most significant practical caveat to the narrative that "the WordPress plugin problem has been solved."

The fact that there are two types of plugin formats also matters. Native plugins run in the same process as the Astro site, and according to the docs, they have "full access to the runtime." Plugins that require a React-based admin interface fall into this category and are not sandboxed. Even when running on Node.js, there is "no V8 isolate, no resource limits."

The granularity of capabilities is also coarse. The docs admit that "Capabilities are coarse," and a plugin with `content:write` can edit content other than its own. There is also an official `network:request:unrestricted` capability that removes host restrictions. The docs themselves state, "Only install plugins from authors you trust," and ultimately, that does not change. The difference is whether the design limits the scope of damage when that trust is betrayed. The README notes that "EmDash is in beta preview," and version 1.0 has not been released yet.

A rough idea of how the migration proceeds

Start with an audit. Check the number of posts, custom post types and ACF fields, required plugins, permalink structure, and URLs ranking high in Search Console. If WooCommerce or membership features are at the core of your site, it is realistically difficult with the current EmDash. You can create an environment with `npm create emdash@latest`, the admin screen is at `/_emdash/admin`, and you create an administrator using a Passkey for the first time.

WXR is the most reliable method for content, and the docs also refer to it as "The most complete import method." When you pass the file from Tools → Export to Import, it goes through five stages: Connect → Analyze → Prepare Schema → Execute Import → Media Import (optional) (as described on the content-import page of the docs).

The main challenge is the theme. Porting from PHP template hierarchy to Astro components is not a migration but a reconstruction. Content retrieval is done via `getEmDashCollection("posts")`, where the return value is not an array but `{ entries, error }`, and the body text is rendered using `PortableText` imported from `"emdash/ui"`. The note in the docs, "In themes, never use `getStaticPaths()` or `export const prerender = true`," is something those accustomed to Astro are likely to trip over.

On the body text side, unknown blocks during the conversion from Gutenberg to Portable Text remain as raw HTML in `htmlBlock`. The more unique blocks a site has, the more manual review is required. After that, create a mapping table, set up 301 redirects using Cloudflare's Redirect Rules, resubmit the sitemap, and run the sites in parallel for one to two weeks.

So, which one should you choose?

There are clear cases where it is appropriate to continue using a hardened WAF + WordPress setup. If WooCommerce or membership features are central to your revenue, or if you have a large number of custom posts built with ACF. In these conditions, it is more realistic to narrow down Managed Rules with the `wordpress` tag, put Zero Trust Access over `/wp-admin/`, and protect logins with Rate Limiting.

EmDash is worth trying in the opposite scenario. If content is the main focus, plugin dependencies are limited to a few, and you are comfortable working with Astro and Workers. However, there are conditions: you must be able to commit to a paid Cloudflare account (Workers Paid from $5/month), be willing to use it knowing it is a beta preview, and be able to get by with plugins available in the marketplace. If these three conditions are not met, I don't think there is a reason to switch right now.

I think both are valid ways to defend a site. The difference lies in the remaining attack surface. What remains in WordPress is the structure itself where plugins can touch everything on the site. What remains in EmDash is native plugins, coarse capabilities, and the fact that it is in beta. You can apply a WAF to either. The difference is how much the code inside can touch.

Try opening your list of plugins

If you are currently running WordPress, try opening your plugin list and counting them. How many of them can you confirm have not changed ownership since last year? The EssentialPlugin incident was triggered by the fact that the developer changed.

I also intend to set up a verification environment soon and try it out up to the point of importing WXR. If anyone is already using EmDash, please let me know in the comments whether you are paying for Workers Paid or if you are disabling plugins and running it within the free tier.


Reference

EmDash side (all as of July 2026)

Cloudflare Side

Statistics and Case Studies

Related Articles
https://note.com/zephel01/n/n0e9dcf4a88ed

https://note.com/zephel01/n/nb795eb8420a2



#WordPress #Cloudflare #WAF #EmDash #WebSecurity #SupplyChainAttack #Astro #CloudflareWorkers #CMS #SiteMigration

いいなと思ったら応援しよう!

zephel01 サーバー代とコーヒー代になります☕ 役に立ったら応援よろしくお願いします!