WordPress security 2026: Imagick RCE, remote JSON, vibe-coded plugins
EN

WordPress security 2026: Imagick RCE, remote JSON, vibe-coded plugins

Last verified: August 25, 2026
13 min read
Guide
500+ WP projects
Security auditor

CVE-2026-65640 is not "WordPress is insecure." It is Author plus Imagick plus Ghostscript. Miss any one of the three and that path is closed. File scanners still miss the next class: PHP that evals JSON it just downloaded.

WordPress 7.0.4 shipped on 12 August 2026. It was the third core security release in four weeks (7.0.2 on 17 July, 7.0.3 on 6 August). The CVE is authenticated remote code execution through a file that looks like an image. pwn.ai reported it. The patch inspects contents before Imagick. Backports go to 4.7.

This article is that path, the JSON path scanners do not hash, and plugins that went from a chat to production. The WordPress security audit is the commercial surface. Broader runtime hardening (passkeys, read-only disk, edge WAF) is in the hardening guide. Do not mix the two.

If you only remember one AND: Imagick and Ghostscript together, plus someone with upload. Everything else in this piece is how teams miss that AND, or how they install a scanner and think the AND went away.


#What 7.0.2 and 7.0.3 were, so 7.0.4 is not a blur

7.0.2 (17 July 2026) patched a chain: SQL injection in WP_Query (author__not_in) and REST batch route confusion. Chained, unauthenticated admin on default installs from 6.8 up. Searchlight Cyber published the mechanics. That is not Imagick.

7.0.3 (6 August) was a multi-fix release. pwn.ai was among the reporters. Still not Ghostscript.

7.0.4 (12 August) is CVE-2026-65640. Author, upload, Imagick, Ghostscript. Content inspect in load(). Backport to 4.7.

A status meeting that says “we patched WordPress last month” without naming the three numbers is how an Imagick box stays on 7.0.3. wp core version is the check. “The security plugin is green” is not.

Managed WordPress that delays core for “compatibility” is the other miss. 7.0.4 is a content inspect in one editor class. It is not a REST break. If the host will not ship it, policy.xml on that host is the control you still own, or you leave. Waiting for a plugin to “virtually patch” Ghostscript is waiting for a WAF to see C.

Forensic note, because people ask: a successful 7.0.2 chain looks like two HTTP requests and a new administrator. A successful 7.0.4 looks like an Author media upload and a process spawn. The log lines are not the same. If you only grep for user_register, you will miss Ghostscript. If you only grep for gs, you will miss REST batch. Name the CVE when you hunt.


#Imagick, Ghostscript, and Author

ImageMagick can process more than JPEG. PostScript, EPS, PDF go to Ghostscript. WordPress, through Imagick, used to pick the handler from the extension. Imagick then read the bytes. A .png that is PostScript reached Ghostscript. That is CVE-2026-65640 (CVSS 8.8, CWE-434).

Both have to be true:

  1. Imagick and Ghostscript are installed and used for media.
  2. A user who can upload (Author and above) is not fully trusted.

GD-only hosts are outside this path. Imagick without Ghostscript is outside this path. Administrator-only uploads with two people you know is a different risk.

Author is the interesting role. Guest blogs, agencies, “the intern publishes.” Thumbnail generation runs on upload. Nobody opens the file in a desktop app.

7.0.4 changes WP_Image_Editor_Imagick::load() to look at content, reject PostScript and EPS signatures, fake PDFs, archives Imagick would unpack, and handler prefixes. That is the core fix. It is not a substitute for policy.xml on the host.

WordPress 7.0.2 (17 July) was a different class: chained SQL injection in WP_Query plus REST batch route confusion, unauthenticated on default installs from 6.8 up. 7.0.3 (6 August) patched a bag of issues with reporters including pwn.ai. 7.0.4 is the Imagick one. Three releases is the calendar. Treating them as one “WordPress RCE” loses the AND condition that decides whether you stay up tonight.

Upload methods that skip wp_check_filetype_and_ext are the leftover. Core media uses the new inspect. A plugin that writes a file then calls Imagick on the path can still feed Ghostscript. Grep the plugin zip for WP_Image_Editor and for raw Imagick::readImage. The second is the hole the core patch does not cover.


#Ghostscript in policy.xml, not a security plugin

This is the operating choice. Core now inspects the upload. The host still decides which ImageMagick coders exist.

On Debian/Ubuntu the file is often /etc/ImageMagick-6/policy.xml or ImageMagick-7. Deny the delegates you do not need:

<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="EPS" />
<policy domain="coder" rights="none" pattern="PDF" />
<policy domain="coder" rights="none" pattern="URL" />
<policy domain="coder" rights="none" pattern="HTTPS" />

A security plugin cannot write that file. Wordfence does not replace Ghostscript policy. A WAF sees multipart/form-data from a logged-in Author. It does not see the C library after PHP accepted the part.

disable_functions for exec, shell_exec, passthru, system, proc_open is a second fence. It does not stop Ghostscript if Imagick calls it in-process. Treat it as useful, not sufficient.

Shared PHP-FPM pools mean a successful RCE is the pool user, often the same user as every other site on the account. That is why Author on a shared box is a different conversation from Author on a single-tenant VPS. The CVE does not change. The blast radius does.

Patch first. Then policy.xml. Then decide whether Author should upload at all.

PDF thumbnails are the usual objection. If the editorial workflow needs PDF previews, generate them in a worker that is not the public PHP-FPM user, with a policy that allows PDF only in that worker. Do not re-enable PDF on the box that serves wp-admin to Authors. Magazines that must preview PDFs already have a pipeline. Magazines that do not, should not discover they needed Ghostscript from a CVE advisory.

phpinfo in a mu-plugin on staging is how you see the Imagick version without SSHing. Do not leave phpinfo on production. php -i | grep -i imagick on the host is enough.


#Remote JSON that never touches disk

File-integrity plugins compare PHP to wordpress.org zip checksums. That catches a webshell dropped into wp-content/uploads. It does not catch:

  • a “what’s new” feed the plugin file_get_contents and then interpolates into eval or into a template with {php}
  • a remote JSON list of “layout presets” decoded and passed to create_function leftovers
  • an update checker that runs a phar from a vendor CDN

Disk is clean. Runtime is not. The admin user that appears on Tuesday was created by a payload that never sat in git.

We do not have a public count of “seven plugins” that is ours to cite. The class is enough: if the plugin’s useful behaviour arrives over HTTPS from a host you do not pin, treat it as executable input. Pin the URL, pin the hash, or remove the plugin.

JSON is not evil. wp_remote_get plus json_decode plus escaped output is fine. The failure is decode then execute.

Timeouts and size caps belong on those requests. A 20 MB JSON “template pack” is not a notice. It is a download you did not mean to run. wp_remote_get with timeout 5 and a byte limit, then json_decode, then allow-list keys. Anything else is an interpreter.

The vendor hostname should be pinned. If the plugin concatenates a path onto a filterable base URL, a site owner with manage_options can already point it at evil. That is a feature until an Author-level bug or a stolen cookie uses the same option. Capability checks on the settings screen are not the same as not executing remote strings.


#Vibe-coded plugins on production

A chat that emits a plugin zip is faster than a review. Production does not care about faster.

What we still open in those zips:

  • $wpdb->query("… $unsanitised …") without $wpdb->prepare
  • file_get_contents of a vendor URL on admin_init
  • update_option of a whole JSON blob from POST without a capability check beyond read
  • CSS dumped inline, which is a vitals problem, not an RCE, and still ships because nobody looked

The hardening guide is the runtime. This section is the supply of new PHP. Composer lockfile plus a read of eval and remote fetches before the plugin enters production. Auto-install from the dashboard is how vibe-coded code skips that read.

Authors who can upload are also the CVE-2026-65640 condition. A vibe-coded form plugin that grants Author to “clients who send stories” recreates the Imagick path on purpose.

Composer cannot save you if the zip never entered composer. Dashboard “Add plugin” is the vibe-code on-ramp. Production should not allow it. Staging can, if staging cannot reach Imagick+Ghostscript or cannot reach the live database. We have watched a “test” plugin on a clone that still had production wp-config constants. That is not a CVE. That is a clone.

Review is a grep, not a ceremony: eval, assert(, create_function, unserialize(, file_get_contents of http, $wpdb->query with interpolation, update_option from $_POST without manage_options. An hour. The chat will not do it.


#What actually changes this week

  1. wp core version. If you are below 7.0.4 on the 7.0 line, or missing the backport on 6.x / 4.7+, patch.
  2. php -m | grep imagick and whether gs exists. If both, policy.xml today.
  3. Plugin list: anything that loads a dashboard “feed” or “templates” from the vendor. Open the PHP. If it evals, it goes.
  4. Role list: how many Authors can upload. Cut the ones who write drafts only.
  5. Logs off-box, from the hardening guide. An RCE that wipes auth.log on the same disk is a guess, not an incident.

Do not install a second scanner as the response to a library delegate. Scanners hash files.

Roles, written down:

RoleCan uploadIn the CVE-2026-65640 ANDWhat to do
SubscribernonoFine
ContributornonoFine for drafts
Authoryesyes if Imagick+GSReview each account
EditoryesyesSame
AdministratoryesyesExpected, still patch

If the magazine must have guest Authors, they can write without upload_files. That capability is the cheapest close when you cannot take Imagick out.


#Media plugins that call Imagick themselves

Core is patched. Plugins that instantiate Imagick on a temp file after a custom upload field are not. Product image import, bulk “optimize,” PDF flyer generators, “client dropbox” mu-plugins. They never hit WP_Image_Editor_Imagick::load().

Grep is the inventory: new Imagick, readImage, ImagickPixel. If you find them, either they go through the same content inspect as core, or they lose Ghostscript on that box, or they move to a worker. Leaving them because “we patched WordPress” is the 7.0.3 meeting again.

WooCommerce product import of CSV with image URLs is a fetch-then-Imagick path. The bytes never went through the media modal. Treat import as upload. Run it as an admin on a box that already has policy.xml, not as a cron on a host that still has PDF delegates for “the print catalogue.”

SVG is not this CVE. SVG can still be script in a browser if you serve it as image/svg+xml to logged-out users. Different bug, same upload capability. If Authors upload SVG, serve it as download or sanitise. Do not confuse it with Ghostscript. Mixing the two in a ticket is how neither gets a policy.

WebP and AVIF go through Imagick on many stacks without Ghostscript. That is the common, safe path. The AND is Ghostscript for PS/EPS/PDF. If convert -list delegate shows gs for those, you are in the advisory. If it does not, you are in 7.0.4 for hygiene and you can sleep.


#Audit and further reading

The security audit is Imagick/Ghostscript, Author, remote JSON, and the plugin zip you did not read. Passkeys, read-only disk, and edge WAF stay in advanced hardening.

CVE-2026-65640 is one path. policy.xml is the control that still matters when the next similar bug is filed. JSON that executes is a different path. Vibe-coded zips are a third. A plugin page that says “protected” addresses none of them by itself.

We do not quote a percentage of WordPress sites that run Imagick+Ghostscript. Hosts differ. The only number that matters on your box is the AND: php -m, which gs, how many Authors. GuardingWP’s 53 percent unpatched-CVE figure lives in a different article and is a different scan. Do not paste it onto Imagick and call it this CVE.

If the answer to “do we have Ghostscript” is “the host would know,” you do not have a control. You have a ticket. policy.xml is a file. Ask for the file, or move.

Staging clones that copy production policy.xml with PDF allowed “because design needs flyers” are how the AND returns after you closed it on live. Staging should be stricter, not looser. If staging must preview PDFs, that is a second ImageMagick policy for a second user, not a copy of production with extras turned on.

The backport to 4.7 means old branches got load() inspect too. “We are on 6.4 because the theme” is not an excuse to skip the security release on that branch. wp core update to the patched 6.4.x / 6.7.x / 4.7.x that contains the inspect. Confirm in the release notes, not in a changelog tweet.

The public catalog on Astro does not upload media. That is why headless helps anonymous traffic and does not close Author. wp-admin is still PHP. The AND still lives there. Build the catalog static. Keep policy.xml on the origin that still accepts async-upload.php.


#Conclusion

Three core security releases in four weeks is the cadence, not a slogan. The August one needs Author, Imagick, and Ghostscript. Patch core. Deny Ghostscript coders on the host. Stop eval of remote JSON. Keep chat-exported plugins off production until someone reads them. Write with the PHP version, whether Imagick is loaded, and how many Authors upload, if you want that inspected.

The next similar bug will have a new CVE number. policy.xml, no eval of remote JSON, and no dashboard plugin installs on production will still be the list. A fourth scanner will not.

Incident week, if you already had Author+Imagick+GS unpatched: assume the box is not yours until you prove it. Snapshot. Rotate salts in wp-config.php. New admin password, new application passwords. Compare users for unexpected Authors. Compare must-use plugins to git. The JSON class can create an admin without a file change, so a clean zip of wp-content/plugins is not the all-clear. Off-box logs from the hardening guide are how you see the POST that created them.

Application passwords and XML-RPC are adjacent, not this CVE. They are how a stolen Author becomes a scripted upload. Turn XML-RPC off if nothing needs it. Application passwords for CI belong in the secret store, not in a staff password manager shared with editorial. That is identity, from the hardening piece. It lowers the chance that CVE-2026-65640 is reachable. It does not patch Imagick.

Next step

Turn the article into an actual implementation

This block strengthens internal linking and gives readers the most relevant next move instead of leaving them at a dead end.

Article FAQ

Frequently asked questions

Practical answers to apply the topic in real execution.

SEO-readyGEO-readyAEO-ready5 Q&A
Does every WordPress site need an emergency patch for CVE-2026-65640?#
If Imagick and Ghostscript are both in use and people you do not fully trust hold Author, yes. If you run GD only, update on the normal schedule and still patch. The advisory is AND, not OR.
Why did file scanners miss JSON feed attacks?#
They checksum PHP on disk. The malicious bytes arrived in a fetched JSON document. Disk did not change.
Is a WAF enough against Imagick RCE?#
No. The upload is an authenticated media POST that looks like an image. The dangerous work is Ghostscript on the server after PHP has accepted the file.
Can Authors stay on the site?#
Yes, with upload capability reviewed. Contributor without upload is the cheaper control if they only write drafts.
Does headless WordPress remove this RCE?#
It removes anonymous PHP from the catalog. wp-admin and media upload still run PHP. Authors still upload. policy.xml still matters.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles