Conversion to a static or SSR Next.js front end eliminates some vulnerability classes outright and only shrinks others. The right candidates depend on which category a site falls into.
Most CVEs
live in plugins and themes, not core
5 classes
largely removed by conversion
Not all
sites are conversion candidates
4 steps
to triage an existing WordPress site
Sources: Wordfence, Patchstack, WPScan vulnerability databases; CVE records for WordPress plugins and themes; Next.js security advisories including the 2025 middleware CVE; arvintech site conversions 2023–2026.
The point
Moving a WordPress site to a static or SSR Next.js front end eliminates some vulnerability classes outright and only shrinks others. The best candidates depend on which category a site falls into.
WordPress is not uniquely poorly written. It is uniquely exposed: a public PHP application, a public admin, a live database, and a plugin marketplace that most sites depend on. Automated scanners hammer that surface continuously. Conversion is useful when that surface is the problem — and it is the problem for a large share of brochure, marketing, and blog sites.
Eliminated
Plugin/theme CVEs on the public site, wp-admin and xmlrpc.php, PHP web shells, front-end SQL injection.
Shrunk
Backend risk if WordPress stays headless and locked down. Editor workflows move behind authenticated tooling.
Unchanged or new
npm dependency risk, Next.js middleware and SSRF issues, forms, analytics, and third-party scripts.
These are the classes that disappear when the public site is not WordPress — not because Next.js is magically secure, but because the attack surface is no longer there.
The vast majority of WordPress CVEs are in third-party plugins and themes: SQL injection, XSS, arbitrary file upload, privilege escalation, and auth bypass. A Next.js front end has no plugin layer exposed to the public. Capabilities live in explicit code and declared npm dependencies, not in a marketplace of independently maintained PHP packages.
Deep diveBrute force, credential stuffing, and XML-RPC amplification attacks disappear when those endpoints are not on the public site. Content changes go through Cursor, Git, and a host — not through a browser login that scanners probe with credential lists around the clock.
Web shells, malicious file uploads, and writable directories matter much less when the public site is static files or a serverless function. There is no PHP process writing into a public uploads directory on every request.
Deep diveSQL injection through plugin search forms, filters, and custom queries goes away when the page does not query the database at request time. A visitor reading a marketing page gets a pre-built document from the edge — not a live MySQL round-trip.
Sites running unmaintained plugins are the highest-risk group, since these never get patched. Conversion removes the entire class: there is no abandoned plugin to forget, because there is no plugin runtime on the public site.
WordPress core is patched on a cadence that most site owners can follow. The plugin graph is not. That is where the volume, the delay, and the worst outcomes live.
Why plugins, not core
Every plugin runs inside the same PHP process, with the same file-system rights and the same database credentials as WordPress itself.
There is no sandbox. A contact-form plugin, a slider, a page builder, and a caching plugin all execute as the site. A flaw in any one of them is a flaw in the whole application. Wordfence, Patchstack, and WPScan consistently show that the large majority of published WordPress CVEs sit in third-party plugins and themes — not in WordPress core. Core is a single, well-watched codebase. The plugin directory is tens of thousands of independently written PHP packages, many of them maintained by one person, a small shop, or nobody at all.
These are the recurring bug families. They are listed as categories of failure, not as recipes. The operational fact is that scanners look for known instances of each class across millions of public sites the day a CVE is published.
| Class | What failed in the plugin | What it usually costs the site |
|---|---|---|
| SQL injection | User input concatenated into a database query instead of parameterized. Search forms, filters, AJAX handlers, and custom tables are the usual location. | Read, change, or delete content and accounts. In the worst cases, dump wp_users and reset an admin. |
| Cross-site scripting (XSS) | Output not escaped. Stored XSS in a review, form, or builder widget is worse than reflected XSS because it runs for every later visitor or editor. | Session theft, admin takeover from a logged-in editor, malware injected into pages Google then flags. |
| Arbitrary file upload | The plugin accepts a file and does not restrict type, location, or execution. Upload handlers, import tools, and "backup restore" features are frequent. | A PHP file lands under a web-reachable directory. That is a foothold. Persistence usually follows. |
| Missing capability / nonce checks | An AJAX or REST action runs without verifying that the caller is allowed to do it, or without a CSRF token. | A subscriber, or sometimes an unauthenticated visitor, performs an admin-only action: create a user, change settings, install a plugin. |
| Authentication bypass | A custom login, SSO, membership gate, or "remember me" handler trusts a cookie, header, or parameter it should not. | The membership or admin boundary disappears. The rest of the site's permission model is then irrelevant. |
| Privilege escalation | A lower-privilege role can change its own role, edit options, or call an admin callback. | Editor becomes admin. Contributor becomes editor. From there, plugin install and file edit are often one click. |
| Insecure deserialization | PHP unserialize() on data the visitor can influence. Object injection turns gadget chains in the plugin or core into unexpected code paths. | Often remote code execution when a usable gadget exists — which is why this class is treated as critical even before a full chain is public. |
| Local/remote file inclusion | include/require built from a request parameter, or a path that can leave the intended directory. | The PHP process loads a file the author did not intend — sometimes a remote URL on misconfigured hosts, more often a local file already written by an upload bug. |
A CVE is public. Exploit kits are updated the same day. The plugin author may patch in hours or in weeks. Site owners patch when they notice, when auto-update is on, or never. That gap is the operational risk — not the existence of a patch in the abstract.
No update in over a year is the highest-risk group. The author moved on, sold the plugin, or vanished. The CVE still gets a number. The site still runs the code. Auto-update cannot save a plugin that has no new release.
"Free" premium themes and plugins are a common infection vector. The zip already contains a backdoor, a phone-home, or a hidden admin. Updates, if they exist, may reintroduce the payload. These installs should be treated as compromised until proven otherwise.
Owners delay patches because the last update broke Elementor, WooCommerce, or a custom theme. That is rational from a business-uptime view and disastrous from a security view. The plugin model forces that tradeoff. A compiled Next.js site does not: you review a pull request, preview a URL, then deploy.
Page builders are large PHP applications
Elementor, Divi, WPBakery, and similar tools are not "a plugin." They are full rendering engines with their own widgets, AJAX, file handling, and template language. They concentrate CVEs because they concentrate code — and they run on the public site, not behind a build step.
SEO, cache, form, and backup plugins sit on every request
These are the plugins almost every SMB site installs. They touch every page view, every form post, or the entire file system (backups). A bug in a ubiquitous plugin is a bug in a large fraction of the WordPress web, which is why they are scanned first.
Themes are plugins with a different label
A theme is PHP that renders the public site. Nulled themes, purchased-once-and-never-updated themes, and "multipurpose" themes with bundled plugins carry the same classes as plugins. Hiding the theme name does not hide the vulnerability; scanners fingerprint anyway.
Supply chain is the plugin directory itself
Legitimate plugins have been sold, compromised, or had a maintainer account taken over. A trusted slug can ship a bad update. WordPress auto-update then distributes it. That is a supply-chain event, not a "forgot to patch" event.
What conversion changes: there is no public plugin runtime. A form, a slider, or SEO metadata is a component or a metadata file in a repository you own. Dependencies are declared in package.json and audited. That does not mean npm is risk-free. It means the site is no longer a marketplace of PHP packages executing with full application privilege on every visitor request.
Plugin bugs are how most incidents start. PHP and a writable web root are how they become a persistent compromise. The two are one system.
The runtime model
On a typical WordPress host, a public HTTP request can cause the server to execute PHP, read and write files, and talk to MySQL — in the same process, with the same user the site runs as.
That is a normal application server. It is also why WordPress incidents look the way they do. Once an attacker can cause PHP to run a file they control, they do not need a new CVE every week. They have a foothold: a small PHP file in uploads or an extra admin user, used to maintain access, inject spam, or pivot. Static files and serverless functions do not offer that loop. A pre-built HTML document at the edge cannot write a new executable into the public site.
WordPress, the theme, and every plugin drop PHP files under a web-reachable tree. Scanners enumerate wp-content/plugins/, wp-admin/, xmlrpc.php, and leftover installer files. Unused plugins still expose PHP. "Deactivated" is not "deleted from disk."
The uploads directory must be writable for media to work. If the host also executes PHP from that directory — the default on many shared hosts — a successful upload bug becomes a web shell. Hardening (deny PHP execution in uploads) is well-known and still missing on a large share of SMB sites.
Cleanup companies spend most of their time finding PHP droppers, not patching the original plugin. Files hide under cache folders, old theme copies, and randomly named uploads. If the writable directory remains, reinfection is the next scanner cycle.
PHP loads other PHP files by path. Plugins that build that path from a request, a cookie, or a poorly validated option can load a file the author did not intend. Combined with an upload, this is a classic two-bug chain. Neither bug looks dramatic in isolation.
PHP's unserialize(), extract(), eval(), and older patterns like create_function() turn attacker-controlled strings into program behavior. WordPress core has reduced its own use of these. Plugins still ship them, especially older ones copied forward for years.
Database credentials, salts, and often third-party API keys live in wp-config.php on the server. A file-read bug, a backup zip left in the web root, a misconfigured host that serves .php as text, or a directory listing can expose it. From there the database is no longer "behind" the application.
A surprising number of SMB WordPress sites still run PHP versions that no longer receive security fixes. WordPress may still boot. Plugins may still "work." The runtime underneath them does not get patches. That is a host problem and a plugin problem at once: old plugins often cannot move to current PHP, so the owner stays on the old runtime to keep the site up.
Many WordPress sites share a machine with other customers. Weak isolation, world-writable directories, and leftover backup files are common. A compromise on an adjacent account is not a WordPress CVE — it is still a WordPress incident if the web root is writable.
Directories at 777, the web user owning the whole tree, and plugins that "need write access to install themselves" are the default story on cheap hosting. The plugin model assumes the application can write to itself. That assumption is convenient for auto-update and lethal after a foothold.
Old copies of wp-admin, migration scripts, phpinfo files, backup zips of the whole site, and unused plugins remain after a redesign. Each is still executable or downloadable. Conversion to static output is one of the few processes that actually deletes this class, because the new public site is a build artifact, not a living directory of PHP.
Still WordPress
Static / SSR Next.js front end
These sites get the most security benefit for the least rebuild cost. Conversion here is usually a net win on security, speed, and maintenance.
Content that changes infrequently does not need a live PHP application assembling every page. Static or ISR delivery is a better fit, and the public attack surface collapses.
Sites with a long plugin list and a history of hacks, malware cleanups, or Wordfence/Sucuri alerts. Conversion is cheaper than another cleanup cycle plus the next one.
Sliders, forms, SEO tags, caching, and page builders often exist because WordPress needs them. On Next.js those are components, metadata, and host-level caching — not extra PHP packages.
Performance and Core Web Vitals are SEO. Pre-rendered pages on an edge network routinely beat plugin-heavy WordPress on LCP, INP, and CLS without a caching plugin stack.
Conversion still reduces public attack surface. It is just a larger project — and sometimes the honest recommendation is to harden WordPress rather than rebuild it.
Heavy plugin dependence means you would be rebuilding checkout, accounts, and subscriptions. That is a commerce project, not a front-end conversion. Keep WordPress (or move to a dedicated commerce platform) unless the business is ready to fund a rebuild of those flows.
Sites where editors rely on the WordPress editor and page builders like Elementor or Divi. Removing the visual builder without a replacement CMS is a people problem, not a security win. Pair conversion with a CMS they can actually use — or do not convert yet.
Custom types, many third-party integrations, or learning-management plugins encode years of operational logic. Rebuilding that is a product rewrite. Security work here is usually lock-down, patching, and reducing the public plugin surface — not a full Next.js migration.
A Next.js front end is a different attack surface, not an empty one. Selling conversion as “no more vulnerabilities” is a lie. These are the remaining and new risks.
If you keep WordPress as the CMS behind Next.js, the backend and its plugins still need patching. You can lock it down — private network, no public admin, WPGraphQL or REST only through the server — but abandoned plugins on the CMS are still abandoned plugins. Conversion of the public site is not conversion of the CMS.
Dependency vulnerabilities in npm packages, middleware authorization bypass issues (including the 2025 Next.js middleware CVE), SSRF through image optimization or server actions, exposed environment variables, and misconfigured API routes. These are real. They are also smaller, more inspectable, and more routinely audited than a plugin marketplace — but they require the same discipline WordPress owners skipped.
Contact forms, analytics, and embeds still need spam protection and a review of what they load. Conversion does not make a leaked form-submission inbox or a compromised tag manager go away. Third-party scripts remain a supply-chain decision.
The honest comparison
WordPress risk is mostly unmaintained third-party PHP on a public application. Next.js risk is mostly application code, dependencies, and configuration. One is a marketplace of unknown authors. The other is a repository you own. That is the security argument — not that the second stack cannot be broken.
Four steps decide whether a WordPress site should be converted, hardened, or left alone.
Run WPScan or the Wordfence/Patchstack vulnerability databases against the plugin and theme list and version numbers. Known CVEs are not theoretical; they are often already in automated exploit kits.
Known unpatched CVEs, abandoned plugins (no update in over a year), or nulled/pirated themes. These three flags alone often justify conversion or an emergency plugin cull.
Is the content mostly static? Do editors need a visual builder? A brochure site with a developer updating copy is a conversion. A daily publisher living in Elementor is not — unless you also pick a CMS they will actually use.
Headless WordPress, Sanity, Contentful, MDX, or similar — based on that editor need. If nobody needs a visual editor, MDX in the repo is often enough. If marketing needs to ship pages without a developer, a headless CMS is the conversion, not a Git-only workflow.
Score each row 0–2. Totals of 10 or higher usually mean convert. 5–9 means harden or convert with a CMS. Below 5 means leave WordPress and patch.
| Factor | 0 — stay | 1 — mixed | 2 — convert |
|---|---|---|---|
| Plugin count | Under 8, all maintained | 8–20, mixed quality | 20+, abandoned, or nulled |
| Known CVEs | None unpatched | Patched but recurring alerts | Unpatched CVEs in production |
| Incident history | Clean | Malware cleanup once | Repeat hacks / Sucuri / Wordfence fires |
| Content change rate | Daily visual editing | Weekly in Gutenberg | Infrequent; developer can ship it |
| Commerce / membership | Woo, LMS, subscriptions | Simple forms and bookings | Brochure, portfolio, marketing, blog |
| Editor dependency | Elementor / Divi daily | Needs a CMS, not a builder | No visual builder required |
| Performance / SEO | Fast enough; caching OK | Core Web Vitals uneven | Slow; Vitals blocking rankings |
| Integrations / CPT complexity | Many custom types + APIs | A few integrations | Standard pages and posts |
10–16
Convert
Static or SSR Next.js. Pick MDX or a light CMS from editor need.
5–9
Harden or convert with CMS
Cull plugins now. Convert if a headless CMS covers editor workflow.
0–4
Keep WordPress
Patch, lock down admin, remove abandoned plugins. Rebuild later if the product changes.
arvintech still builds WordPress sites when that is the honest fit — WooCommerce, membership, or a team that lives in a visual builder. For brochure, marketing, portfolio, and blog sites with plugin risk, we convert to Next.js on Vercel because the public attack surface those sites carry is no longer justified.
The question is not “is WordPress insecure?” The question is whether this site still needs a public PHP application, a plugin graph, and a live database to publish pages that barely change.
Related reading