Audit #32 Benign
Show full summary
Verdict: benign — portfolio-wide guideline violation, not malware. On 2026-04-27 WordPress.org closed 83 plugins from WPFactory's family of author accounts (wpcodefactory, algoritmika, and woobewoo) in a single one-hour wave. The trigger was a public report alleging a backdoor in WPFactory's paid (non-wp.org) "EU/UK VAT for WooCommerce Pro" plugin — a file class-alg-wc-eu-vat-customer.php that allegedly downloaded an external ZIP, modified WordPress directories, and transmitted data to a remote server.
We audited all 83 closed plugins. None contain the named backdoor file. None contain malware. A 16-category IOC regex sweep returned zero hits, and a follow-up file-by-file LLM review of every PHP file in every plugin's HEAD release found no third-party uploaders, no hidden persistence, no update-channel hijacking, no auth backdoors, and no phone-home + RCE pairings.
51 of 83 bundle one or both of these vendor libraries: vendor/wpfactory/wpfactory-cross-selling and vendor/wpfactory/wpfactory-promoting-notice. Both are admin-promo-banner libraries that phone home to wpfactory.com to fetch banner content and render it in the WordPress admin UI. Neither has user-facing opt-in. WordPress.org's plugin guidelines require informed user consent for phone-home behavior. This is the actual reason WordPress.org closed the portfolio.
The other 32 plugins don't bundle either library. Several are legacy extendWP / taz_bambu / webdeveloping.gr plugins acquired by WPFactory and dormant for years. They were closed by author-association in the portfolio-wide action, not by per-plugin code review.
Three days after closure WPFactory pushed releases (eu-vat-for-woocommerce v4.6.2 on 2026-04-30, product-quantity-for-woocommerce v5.3.0 on 2026-04-30) that still contain the violating libraries. The boundary diffs are routine feature work. The library that triggered the closure is unchanged.
Sites running any of these plugins are not compromised. The libraries are noisy admin-banner phone-homes, not malware. But your "closed pending review" plugin's vendor has not removed the code that triggered the closure.
Audit retained for the record. No action required.
Affected plugins (83)
All plugins covered by this incident report. Combined exposure: 202k+ active installs across 83 slugs.
Plugin version history
Every release on wp.org for this plugin. The plugin was closed by wp.org pending review, but this audit found no malicious code in any version. Sites already running it are not exposed to a security incident — see the cleanup section below for non-emergency guidance.
-
Earlier 167 earlier releases
-
1.0.0 -
1.0.1 -
1.1.0 -
1.2.0 -
1.2.1 -
1.3.0 -
1.4.0 -
1.4.1 -
1.5.0 -
1.6.0 -
1.6.1 -
1.7.0 -
1.7.1 -
1.7.2 -
1.8.0 -
1.8.1 -
1.8.2 -
1.9 -
2.0 -
2.0.1 -
2.1 -
2.2 -
2.2.1 -
2.2.2 -
2.2.3 -
2.2.4 -
2.2.5 -
2.3 -
2.3.1 -
2.3.2 -
2.3.3 -
2.4 -
2.4.1 -
2.4.2 -
2.4.3 -
2.4.4 -
2.4.5 -
2.5 -
2.5.1 -
2.5.2 -
2.5.3 -
2.5.4 -
2.6 -
2.6.1 -
2.6.2 -
2.6.3 -
2.7 -
2.7.1 -
2.7.2 -
2.7.3 -
2.7.4 -
2.8 -
2.8.1 -
2.8.2 -
2.8.3 -
2.8.4 -
2.8.5 -
2.9 -
2.9.1 -
2.9.2 -
2.9.3 -
2.9.4 -
2.9.5 -
2.9.6 -
2.9.7 -
2.9.8 -
2.9.9 -
2.9.10 -
2.9.11 -
2.9.12 -
2.9.13 -
2.9.14 -
2.9.15 -
2.9.16 -
2.9.17 -
2.9.18 -
2.9.19 -
2.9.20 -
2.9.21 -
2.10.0 -
2.10.1 -
2.10.2 -
2.10.3 -
2.11.0 -
2.11.1 -
2.11.2 -
2.11.3 -
2.11.4 -
2.11.5 -
2.11.6 -
2.11.7 -
2.11.8 -
2.11.9 -
2.11.10 -
2.11.11 -
2.11.12 -
2.12.0 -
2.12.1 -
2.12.2 -
2.12.3 -
2.12.4 -
2.12.5 -
2.12.6 -
2.12.7 -
2.12.8 -
2.12.9 -
2.12.10 -
2.12.11 -
2.12.12 -
2.12.13 -
2.12.14 -
3.0.0 -
3.0.1 -
3.1.0 -
3.1.1 -
3.1.2 -
3.1.3 -
3.1.4 -
3.1.5 -
3.1.6 -
3.2.0 -
3.2.1 -
3.2.2 -
3.2.3 -
3.2.4 -
4.0.0 -
4.1.0 -
4.2.0 -
4.2.1 -
4.2.2 -
4.2.3 -
4.2.4 -
4.2.5 -
4.2.6 -
4.2.7 -
4.2.8 -
4.2.9 -
4.3.0 -
4.3.1 -
4.3.2 -
4.3.3 -
4.3.4 -
4.3.5 -
4.3.6 -
4.3.7 -
4.3.8 -
4.3.9 -
4.4.0 -
4.4.1 -
4.4.2 -
4.4.3 -
4.4.4 -
4.4.5 -
4.4.6 -
4.4.7 -
4.4.8 -
4.4.9 -
4.5.0 -
4.5.1 -
4.5.2 -
4.5.3 -
4.5.4 -
4.5.5 -
4.5.6 -
4.5.7 -
4.5.8 -
4.5.9
-
-
4.6.0Audit baseline Last clean release before incident -
4.6.1Released Clean (post-cleanup) -
4.6.2Audit head First malicious release (head of audit)
The closure event
2026-04-27, ~10am UTC: WordPress.org closes 83 plugins in approximately one hour across the WPFactory family of author accounts (wpcodefactory,algoritmika,woobewoo). Public closure notice on each plugin's wp.org page reads: "This plugin has been closed as of April 27, 2026 and is not available for download. This closure is temporary, pending a full review."
Trigger: a wp-content.co article reported a suspected backdoor in WPFactory's paid (commercial-only, non-wp.org) plugin "EU/UK VAT for WooCommerce Pro". File class-alg-wc-eu-vat-customer.php allegedly:
1. Downloaded an external ZIP archive. 2. Modified WordPress directories. 3. Transmitted data to a remote server.
WPFactory initially disputed: "the file does not exist in the official plugin package." Later acknowledged the issue was from "a cached or outdated plugin package." The PRO plugin is not on wp.org and is not in our mirror.
Audit scope
We audited every free plugin closed in the 2026-04-27 wave. 83 plugins total: 65 from wpcodefactory, 15 from algoritmika, 3 from woobewoo. All mirrored as full git repos with per-version tags + real committer attribution at https://plugin-repo.wpbeacon.io/wporg/<slug>.
Plugins on those same author accounts that were closed before the 04-27 wave for other reasons are not included in this audit. They were closed by wp.org for unrelated, individual issues at earlier dates.
Methodology
This audit went deeper than our normal closure triage. The first pass was a 16-pattern regex IOC sweep across all 83 plugins (eval/base64, gzinflate, eval-of-superglobals, shell_exec, create_function, assert-of-superglobals, preg_replace /e, file-write persistence, known campaign C2 domains). It returned zero hits.
A regex sweep can miss anything obfuscated, renamed, or split across files. So the second pass was a file-by-file semantic review run by Claude Code agents in parallel batches. Each agent read every PHP file in the plugin's HEAD tag and looked for:
- Third-party uploaders: any code that fetches an external archive (ZIP, tar, phar) and extracts it into the WordPress filesystem.
- Hidden persistence: writes to
wp-config.php,.htaccess,mu-plugins/, theme functions, or*.phpfiles insideuploads/. - Update-channel hijacking: PUC (plugin-update-checker) library variants, custom
pre_set_site_transient_update_pluginsfilters that route to non-wp.org endpoints, or "self-hosted update" checks that pull from a vendor domain. - Auth backdoors: hardcoded user creation, role escalation, magic-key authentication, password-reset shortcuts.
- Phone-home + RCE pairings: any HTTP call where the response is then
eval'd,unserialize'd,include'd, or written to a.phpfile. - Disguise: random-named files, base64-encoded payloads, bytewise-constructed function names, deliberate string fragmentation.
- Telemetry / analytics inside the free plugin that runs before user opt-in, or that bypasses opt-in toggles.
- Article-pattern signature: the specific combination from the wp-content.co report — ZIP download + WP-dir-modify + remote-POST in the same code path.
The article's named filename class-alg-wc-eu-vat-customer.php was searched across every tag in every plugin's full git history, not just HEAD.
Results
| Verdict | Count | Meaning |
|---|---|---|
| MALICIOUS | 0 | Confirmed backdoor with intent |
| SUSPICIOUS | 0 | Behavior worth flagging publicly even without proven intent |
| GUIDELINE | 51 | Bundles the cross-selling/promoting-notice library OR ships hardcoded "Buy Now" / "Go Premium" admin upsells. Compliance issue, not malware |
| CLEAN | 32 | No vendor library, no upsell strings, no IOCs |
The article's named backdoor file does not exist
class-alg-wc-eu-vat-customer.php has never appeared in any version of any of the 83 free plugins. Git history goes back 11 years on the oldest plugin in the closure-wave corpus. No version of eu-vat-for-woocommerce (the free companion to the paid plugin) has ever shipped that file.
The file that DOES exist in eu-vat-for-woocommerce is a sibling: includes/class-alg-wc-eu-vat-customer-meta-field.php. It's an admin profile field implementation. No HTTP calls. No file writes. No exec primitives. Different code, different purpose.
WPFactory's denial about the file's existence in the free package was technically true.
The actual closure trigger
51 of the 83 plugins bundle one or both of these vendor libraries:
vendor/wpfactory/wpfactory-cross-selling/— fetches admin banner JSON fromwpfactory.com/wp-json/advanced-ads/v1/groups.vendor/wpfactory/wpfactory-promoting-notice/— sibling library, similar admin-banner mechanism.
Both load automatically on plugin install. Both call out to wpfactory.com without user opt-in. Both render promotional content for other WPFactory products in the admin UI on the user's site. WordPress.org's plugin guidelines require informed consent for phone-home behavior; these libraries don't have it.
This is class-consistent with prior wp.org guideline-enforcement waves against bplugins, the legacy algoritmika portfolio, and woobewoo noted in our 2026-04-30 triage memory.
Other notable findings (not verdict-changing)
Live Mixpanel SDK pre-opt-in
Three plugins ship the Mixpanel JS SDK and load it in the WordPress admin before any user-facing opt-in toggle is checked: woo-currency, woo-product-filter, woo-product-tables. The SDK fires page-view events to api.mixpanel.com from the wp-admin context. There is later code in each plugin that reads an opt-in setting, but the SDK has already initialized and pinged Mixpanel by the time that code runs. wp.org guidelines require informed consent before any third-party tracker fires.
wpcodefactory-helper self-hosted update channel
Several in-scope plugins reference a separate companion plugin called wpcodefactory-helper that, when installed, routes update checks for the WPFactory portfolio through wpfactory.com instead of wp.org. The helper itself is not part of this audit (it was closed by wp.org in October 2024 and has been distributed only from wpfactory.com since). Sites that install it are taking plugin updates from WPFactory's infrastructure, not from wp.org's. This is the same architectural concern as the audit-29 greenshift pattern: a free plugin with a self-hosted update channel that can deliver code without wp.org review. Not malicious in itself, but a design choice site admins should be aware of.
Mis-attribution
Several of the 83 plugins are labeled in wp.org as wpcodefactory-owned but originated with prior authors:
awesome-shortcodes—taz_bambulegacy.crm-erp-business-solution,my-woocommerce-product-virtual-showroom,users-import-export-with-excel-for-wp,webd-woocommerce-product-excel-importer-bulk-edit—extendWPacquisition.webd-woocommerce-advanced-reporting-statistics—webdeveloping.gracquisition.
These plugins largely don't contain modern WPFactory code. They were swept up in the portfolio-wide closure because the wp.org account moved with the acquisition.
Post-closure releases still ship the violating code
WordPress.org closed the plugins on 2026-04-27. WPFactory continued pushing releases to SVN.
| Plugin | Version | Date | Days post-closure | Library still bundled |
|---|---|---|---|---|
eu-vat-for-woocommerce | v4.6.2 | 2026-04-30 | +3 | yes (cross-selling) |
product-quantity-for-woocommerce | v5.3.0 | 2026-04-30 | +3 | yes (cross-selling) |
Boundary diff eu-vat-for-woocommerce v4.6.1 → v4.6.2: 21 files changed, +937/−186 lines. Bulk of change is the cross-selling banner refresh + WC Blocks checkout integration. No new HTTP/file/exec primitives. No removal of the violating library.
Boundary diff product-quantity-for-woocommerce v5.2.9 → v5.3.0: 11 files, +963/−278. Adds buy-all-stock-button class + JS quantity-step refactor + locale updates. Library unchanged.
Per-plugin verdicts
51 GUIDELINE — bundles vendor library or ships admin upsells
These plugins contain vendor/wpfactory/wpfactory-cross-selling/, vendor/wpfactory/wpfactory-promoting-notice/, or hardcoded "Buy Now" / "Go Premium" / "Upgrade to Pro" admin notices:
add-to-cart-button-labels-for-woocommerce, ajax-product-search-woocommerce, amount-left-free-shipping-woocommerce, back-button-widget, bulk-price-converter-for-woocommerce, color-or-image-variation-swatches-for-woocommerce, compare-products-for-woocommerce, conditional-payment-gateways-for-woocommerce, content-excel-importer, cost-of-goods-for-woocommerce, coupon-by-user-role-for-woocommerce, custom-checkout-fields-for-woocommerce, custom-emails-for-woocommerce, download-plugins-dashboard, ean-for-woocommerce, emails-verification-for-woocommerce, eu-vat-for-woocommerce, export-woocommerce, external-products-currency-for-woocommerce, file-renaming-on-upload, global-shop-discount-for-woocommerce, instant-checkout-for-chatgpt-openai-readiness-for-woocommerce, maximum-products-per-user-for-woocommerce, msrp-for-woocommerce, order-minimum-amount-for-woocommerce, order-status-for-woocommerce, order-status-rules-for-woocommerce, payment-gateways-by-currency-for-woocommerce, payment-gateways-by-customer-location-for-woocommerce, payment-gateways-by-shipping-for-woocommerce, payment-gateways-per-product-categories-for-woocommerce, pdf-invoicing-for-woocommerce, popup-notices-for-woocommerce, price-offerings-for-woocommerce, product-notes-for-woocommerce, product-quantity-for-woocommerce, product-tabs-for-woocommerce, product-xml-feeds-for-woocommerce, products-per-page-for-woocommerce, products-stock-manager-with-excel, related-categories-for-woocommerce, remove-old-slugspermalinks, remove-special-characters-from-permalinks, stock-snapshot-for-woocommerce, stock-triggers-for-woocommerce, store-migration-products-orders-import-export-with-excel, support-ticket-system-for-woocommerce, url-coupons-for-woocommerce-by-algoritmika, webd-woocommerce-advanced-reporting-statistics, wholesale-pricing-woocommerce, wish-list-for-woocommerce, wp-currency-exchange-rates, wpfactory-conditional-shipping-for-woocommerce
32 CLEAN — no vendor library, no upsells
These plugins were closed alongside the rest of the family but contain no violating code on their own. Many are legacy acquisitions that have been dormant for years and don't carry modern WPFactory code at all.
Hijack-indicator matrix (across all 83)
| Indicator | Result |
|---|---|
| Sole / consistent committer over years? | Yes (wpcodefactory, with historical extendWP / taz_bambu / algoritmika for older entries). No sudden new committer pre-closure. |
| Author profile drift? | No. wpcodefactory is the well-known WPFactory commercial vendor. |
| Code-level malware patterns? | No. All 16 IOC categories returned 0 hits across the entire 83-plugin corpus. |
| Outbound C2 / known bad domains? | No. Call-home destinations are vendor-owned (wpfactory.com). |
| Suspicious obfuscation? | No. |
| New SVN credentials before closure? | No. |
| Article's PRO-plugin backdoor signature in any free plugin? | No. The named filename has never existed in any version of any of the 83 plugins; the article's behavioral combination (ZIP download + WP-dir-modify + remote-POST in same code path) does not occur in any free plugin. |
Every classic supply-chain-attack indicator is absent.
Comparable cases
Same closure pattern as several other late-2026 wp.org guideline-enforcement waves:
bplugins/ legacyalgoritmika/woobewooportfolios (April 2026) — same admin-promo library wave (memory:project_2026-04-30_full_triage_zero_open.md).greenshift-animation-and-page-builder-blocks(audit #29) — paid-license activation + commercial upsells inside the free plugin.wp-product-feed-manager(audit #31) — EDD license code + Go Premium upsell, lifted paid product-cap to satisfy review.
All ended up with the same outcome: portfolio-wide guideline closure, no malware, vendor pushes a compliance fix.
What's different about WPFactory
In the comparable cases above the vendors removed (greenshift) or significantly cleaned up (wpcodefactory, wp-product-feed-manager) the violating code in their post-closure releases. WPFactory has not. The post-closure v4.6.2 of eu-vat-for-woocommerce and v5.3.0 of product-quantity-for-woocommerce ship the same admin-promo libraries that triggered the closure. As of this audit's publication WPFactory has not removed the code that wp.org closed them for.
Reproducibility
Every claim in this audit is browseable at https://plugin-repo.wpbeacon.io/wporg/<slug> — full per-version git history with real committer attribution, released to plugin-repo when WP Beacon's mirror picked up each plugin. Every PHP file in every plugin's HEAD tag was read by an LLM agent during the deep-review pass, not just regex-scanned.