If you run Prime Mover – Backup and Migration on any site, update it before you click Export or Restore again. CVE-2026-115806 (CVSS 9.8, published by Wordfence on October 24, 2026) is a PHP Object Injection bug in every version up to and including 2.2.1. The plugin has 10,000+ active installs, and the fix is version 2.2.2.
The attack works in two steps. First, an anonymous visitor posts a comment through wp-comments-post.php, and that comment holds a base64-encoded serialized PHP object. Later, an administrator runs a normal export or restore. Prime Mover’s search-and-replace routine decodes the comment and passes it to unserialize() with no class restrictions. A POP chain in the bundled Freemius library completes the exploit, so the attacker needs no other plugin or theme.
That means a payload can sit in your wp_comments table for weeks without doing anything. Moderation doesn’t stop it, because pending and spam comments are stored in the same table. As of 2026-10-26 I haven’t seen reports of exploitation in the wild, and no public proof of concept has been released. Since the bug details are public, I wouldn’t count on that lasting.
1. Check the version and update (before any export)
Back up first. Use your host’s backup or a plain wp db export, not a Prime Mover export, because a Prime Mover export is exactly what triggers the bug. Then check the version and update:
# database backup that does not touch Prime Mover
wp db export ~/before-primemover-fix.sql
# which version is installed?
wp plugin get prime-mover --field=version
# update to 2.2.2 or later
wp plugin update prime-mover
In the 2.2.2 changelog, the relevant line is “Hardened unserialize implementation to prevent object injection.” If you only installed Prime Mover for a single migration and don’t use it anymore, remove it:
wp plugin deactivate prime-mover && wp plugin delete prime-mover
Can’t update right now? Then don’t run any Prime Mover export, restore, or automated backup until you can. Also consider closing comments temporarily under Settings → Discussion.
2. Find planted payloads in the comments table
Updating closes the hole, but any payload that’s already planted stays in your database, and other code could still process it later. Search every comment status, including spam and trash. A planted payload looks like a single long string of letters, digits, + and /, sometimes ending in =, with no actual words. Serialized objects start with O: and serialized arrays with a:, so their base64 forms begin with Tzo or YTo.
P=$(wp db prefix)
wp db query "SELECT comment_ID, comment_approved, comment_date, comment_author_IP, LEFT(comment_content, 60) AS preview
FROM ${P}comments
WHERE comment_content REGEXP '^[[:space:]]*[A-Za-z0-9+/]{80,}={0,2}[[:space:]]*$'
OR comment_content LIKE 'Tzo%'
OR comment_content LIKE 'YTo%'
ORDER BY comment_date DESC;"
Look at each hit with wp comment get <ID> --field=comment_content. You can decode a payload safely with echo '<string>' | base64 -d, which only prints text. Do not paste it into PHP to “see what it does.” When you’re sure the hits are junk, delete them permanently:
wp comment delete 1234 1235 1236 --force
Make a note of the IPs in comment_author_IP as well. Blocking them in your firewall won’t stop a determined attacker, but it slows down repeat attempts from the same source.
3. Check whether it already fired
This step matters if anyone ran an export or restore on 2.2.1 or older. According to the public write-up, the gadget chain ends in an option write. So check the options an attacker would change to take over the site, then list your administrators:
wp option get siteurl
wp option get home
wp option get users_can_register # should be 0 on most sites
wp option get default_role # should be subscriber, never administrator
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
If registration was turned on, the default role was changed to administrator, or an admin account appeared that you don’t recognize, assume the site is compromised. Follow my complete hacked-site cleanup guide, and don’t just reset the options. Also move any archive exported on a vulnerable version out of the web root, because it holds your whole database.
Why this works
Migration plugins have to search and replace URLs inside serialized data, so they open every row of every table, including wp_comments. Prime Mover’s recursiveUnserializeReplace() treated any value that looked serialized (or base64 of serialized) as trusted. When PHP unserializes an object, it rebuilds an instance of whatever class the string names. During cleanup, that object’s magic methods (__destruct(), __wakeup()) run, and the attacker controls its properties. The Freemius classes shipped inside the plugin supply the “gadget” that turns this into a real write. CVE-2026-115806 is filed as CWE-502, Deserialization of Untrusted Data.
For developers, the fix pattern is simple. If you only need scalars and arrays, tell PHP to refuse objects:
<?php
// Safe: objects become __PHP_Incomplete_Class, no magic methods run
$data = unserialize( $value, array( 'allowed_classes' => false ) );
// Or use WordPress's helper only on data you wrote yourself
$data = maybe_unserialize( $value ); // NOT safe for user input
Note that maybe_unserialize() doesn’t restrict classes. It’s fine for options your own code saved, but not for anything a visitor can type into a form. If you need a format visitors can send you, use JSON (wp_json_encode() / json_decode()).
Prevention
- Delete migration plugins after the move. This is the second migration plugin bug in a short time, after the Duplicator object injection. A plugin that isn’t installed can’t be exploited.
- Turn on auto-updates for plugins you keep:
wp plugin auto-updates enable prime-mover. More handy commands are in my WP-CLI cheat sheet. - Empty spam and trash regularly. Old spam is exactly where a payload like this sits unnoticed.
- Close comments where you don’t need them. Fewer unauthenticated write paths into the database means less to worry about.
OpenPanel tip: Bugs like this are a good reason to back up at the server level instead of through a plugin that runs in PHP over your own database. In OpenPanel’s WordPress manager, the Backups tab creates and restores files, the database, or both. The Updates tab controls how core, plugins and themes update. Nothing in that process unserializes your comments. In cPanel you’d usually do the same through WP Toolkit or Softaculous, depending on what your host installed. The idea is the same either way: keep backups and migrations outside WordPress.
TL;DR
Prime Mover 2.2.1 and older (CVE-2026-115806, CVSS 9.8) will unserialize a base64 payload that any visitor can leave in a comment, and it does so the next time an admin runs an export or restore. Back up with wp db export, update to 2.2.2 (or delete the plugin), and search wp_comments in every status for long base64 strings starting with Tzo/YTo. Delete what you find, then check users_can_register, default_role and your admin list.

