Paid for security, got a backdoor. How the ShapedPlugin build pipeline compromise hit paying WordPress customers
Paid for security, got a backdoor. How the ShapedPlugin build pipeline compromise hit paying WordPress customers
You paid for a Pro plugin, enabled auto-updates, and sleep easy — because you are a commercial customer, not someone running free junk from WordPress.org. Reasonable assumption? That is exactly what thousands of WordPress administrators using ShapedPlugin products thought. And they received a backdoor through the official update channel — the very one they trusted.
On May 21, 2026, attackers injected a malicious loader into the builds of three commercial ShapedPlugin plugins: Product Slider Pro for WooCommerce (before version 3.5.4), Real Testimonials Pro (version 3.2.5), and Smart Post Show Pro (before version 4.0.2). Free versions on WordPress.org were not affected — the attack was precise and deliberately targeted at paying customers. The incident is tracked as CVE-2026-10735 with a CVSS score of 9.8, Critical, enabling unauthenticated backdoor access to compromised sites. CVE-2026-49777 was submitted as a duplicate identifier.
The Wordfence Threat Intelligence team received notification of the incident on June 11, confirmed the compromise on June 12 after downloading files directly from the ShapedPlugin website, and by June 16 the vendor acknowledged the breach. If your site ran any of the three Pro plugins between April and June 2026, treat it as compromised until proven otherwise.
HOW THE ATTACK WORKS
The attack mechanism is two-stage and deliberately layered — each stage covers the next.
Stage one is the file src/Includes/LicenseLoader.php, embedded directly in the plugin distribution package. It fires on the admin_init hook, meaning it executes automatically the moment an administrator opens the WordPress admin panel. The loader connects to a C2 server at 194[.]76[.]217[.]28:2871, downloads the second stage using WordPress’s own Plugin_Upgrader — making the installation look like a normal plugin update — then deletes itself, physically removing the file and leaving minimal forensic trace.
Stage two installs into wp-content/plugins/woocommerce-subscription/ or wp-content/plugins/woocommerce-notification/ — names deliberately chosen to resemble legitimate WooCommerce components. The plugin hides itself from the installed plugin list via the all_plugins filter, so it does not appear in the admin panel. Inside is a ready-made attacker toolkit: Tiny File Manager 2.6 (a full web-based file manager), Adminer 5.2.1 (database management directly from the browser), a backdoor REST API endpoint at /wp-json/wc/v3/settings/apply, a URL-parameter webshell, and an authentication bypass using a hardcoded MD5 hash e268c35a06d85f672e70c9beecb4e5d1.
The chain is short: the administrator opens Dashboard, the loader fires, installs the backdoor, reports the victim’s domain to C2, disappears. The backdoor stays invisible and waits for commands.
WHAT WAS STOLEN
The list of exfiltrated data maps directly to what is most valuable on a site with real transactions. The backdoor was specifically designed to extract user logins and passwords, active session cookies, user roles with a focus on administrators, WooCommerce order data for the past three months including payment method information, SMTP credentials, WordPress security keys from wp-config.php, and the full list of site administrators.
The 2FA secret theft is worth calling out separately. The backdoor was explicitly built to target TOTP implementations in four popular plugins: WP 2FA, Wordfence Login Security, Really Simple SSL, and Two-Factor. It extracts the TOTP seed — the secret from which one-time codes are generated. With the seed, the attacker generates valid 2FA codes independently and completely bypasses the second factor, regardless of how carefully the user set it up.
Alongside data collection, the backdoor gave operators the ability to write arbitrary files to the server via Tiny File Manager or the webshell. In practice, this means placing additional PHP shells and any other code anywhere on the filesystem accessible to the web server. Credentials are stolen once; a file manager is a permanent entry point.
HOW THE BUILD PIPELINE WAS COMPROMISED
Wordfence found no evidence of the plugin files being tampered with after publication. Timestamp analysis showed four files were modified within a two-hour window on May 21, 2026 — behavior consistent with an automated injection process rather than manual editing. According to Wordfence, references to private Git repositories were found inside plugin metadata, and the pattern of changes matched ShapedPlugin’s release workflow.
All of this points to a compromise not of the plugin files themselves, but of the vendor’s build and distribution pipeline — the infrastructure that assembles release ZIP archives and delivers them to paying customers through the official website. That is why the free versions on WordPress.org remained clean: they follow a different publication path. The attackers appear to have had access to both channels and deliberately targeted only the paid one.
This is a classic supply chain attack through the build pipeline. Not a compromise of a specific site, not a vulnerability in plugin logic — but a compromise of the point from which code reaches thousands of customers simultaneously. A recent parallel is the OptinMonster attack via a CDN key in June 2026. Different mechanics, same result: malicious code arrives from a trusted address.
TIMELINE
May 21, 2026 — malicious code injected into Pro builds via the compromised ShapedPlugin build pipeline.
June 10, 2026 — first customer reports of suspicious updates.
June 11, 2026 — Wordfence Threat Intelligence receives notification of a potential compromise.
June 12, 2026 — Wordfence researchers confirm the breach after downloading files directly from the ShapedPlugin website. The compromised Real Testimonials Pro version 3.2.5 is still being served from the official update endpoint.
June 16, 2026 — ShapedPlugin acknowledges the incident and announces the start of an investigation.
June 17–18, 2026 — fixed versions released: Product Slider Pro 3.5.4, Smart Post Show Pro 4.0.2, Real Testimonials Pro 3.2.6.
WHY THIS MATTERS
Paid plugins sell more than functionality — they sell trust. Professional team, commercial accountability, official update channel. ShapedPlugin demonstrated that the update channel itself can be compromised without touching the product. The attackers did not exploit a vulnerability in the plugin’s code or logic — they entered the pipeline that assembles and distributes releases, and from there WordPress itself handled delivery of the malware.
The selective targeting is particularly telling. The attackers had access to both the paid and free channels and deliberately touched only the former. Free WordPress.org users were safe this time. Those who paid were not. The math is simple: paying customers running active WooCommerce stores mean card data, SMTP access to real domains, accounts with transaction history — far more valuable than a test site account.
The CVSS 9.8 score is not a formality here. The attack requires no prior authentication — the backdoor is already inside, waiting only for the first administrator visit to Dashboard. After that, the attacker has Adminer for the database, Tiny File Manager for the filesystem, a webshell for command execution, and all credentials including TOTP seeds. Full control over the site without a single cracked password.
WHAT TO DO
Start here, and do it now: update the affected plugins. Product Slider Pro to at least 3.5.4, Smart Post Show Pro to 4.0.2, Real Testimonials Pro to 3.2.6. But updating only closes the delivery channel — it does not remove the backdoor if it was already installed.
Check the filesystem for fake plugins. You will not see them through Dashboard — the backdoor hides itself via the all_plugins filter. Look directly: search for directories named woocommerce-subscription (singular, not woocommerce-subscriptions) and woocommerce-notification:
ls -la /var/www/html/wp-content/plugins/ | grep -E "woocommerce-subscription$|woocommerce-notification"
If the directory is found, the site was compromised. Remove it, but keep in mind: by this point additional backdoors may have been placed anywhere on the filesystem via Tiny File Manager or the webshell. Checking one directory does not give the full picture.
Reset all credentials: WordPress user passwords, API keys, SMTP passwords. If the site uses any of the four affected 2FA plugins — WP 2FA, Wordfence Login Security, Really Simple SSL, or Two-Factor — revoke TOTP seeds and reissue them for all users. Treat existing QR codes as compromised.
Regenerate the WordPress secret keys in wp-config.php — this immediately invalidates all active sessions. Get fresh values for all eight lines from AUTH_KEY to NONCE_SALT at the official generator: https://api.wordpress.org/secret-key/1.1/salt/.
Audit the administrator list — in this attack accounts were not created automatically (unlike OptinMonster, where developer_api1 appeared), but entries may have been added manually through the obtained access. The command lists only users with the administrator role, showing their ID, login, email, and registration date. That last field is the key one: a new account with a registration date in the May–June 2026 window is a red flag. The --path flag tells WP-CLI where to find the WordPress installation — without it the command fails with “This does not seem to be a WordPress installation”:
wp user list --path=/var/www/html --role=administrator --fields=ID,user_login,user_email,user_registered
If the command fails due to open_basedir restrictions, run it as the web user:
sudo -u www-data wp user list --path=/var/www/html --role=administrator --fields=ID,user_login,user_email,user_registered
Block the C2 address at the firewall level. The rule is added to the output chain and drops all outgoing packets to IP 194.76.217.28 — the attack’s command-and-control server. Even if undetected residual code remains on the server, it will not be able to reach home:
nft add rule inet filter output ip daddr 194.76.217.28 drop
PROACTIVE DEFENSE
Blocking a specific C2 address closes this attack but not the next one. The real protection is restricting outbound connections from the PHP process altogether. A loader like LicenseLoader.php runs as the web user (www-data on Debian/Ubuntu) and connects to the C2 on a non-standard port — 2871 in this case. An nftables rule by uid kills this entire class of attack: PHP can still make HTTP/HTTPS requests outbound, but arbitrary TCP connections to random ports will be dropped:
nft add rule inet filter output skuid www-data tcp dport != { 80, 443 } drop
If WordPress legitimately needs other outbound ports — SMTP directly, for example — add them to the exception list. To check the web user’s uid: id www-data. If your PHP-FPM pool runs under a different user, substitute its name.
At the PHP-FPM level, you can disable the functions a loader uses to open network connections. In the WordPress pool configuration file, typically something like /etc/php/8.3/fpm/pool.d/wordpress.conf, add:
php_admin_value[disable_functions] = fsockopen,pfsockopen,stream_socket_client
This removes the ability to open arbitrary TCP sockets from PHP code. Most legitimate WordPress plugins use cURL or wp_remote_get() for HTTP requests — they will not be affected. After making the change, restart PHP-FPM: systemctl restart php8.3-fpm.
Filesystem monitoring is the only way to catch Stage 2 at the moment it is written — before the loader deletes itself. inotifywait from the inotify-tools package watches the plugins directory and logs immediately when a new file or directory appears:
inotifywait -m -r -e create,moved_to --format '%T %w%f' \
--timefmt '%Y-%m-%d %H:%M:%S' \
/var/www/html/wp-content/plugins/ >> /var/log/wp-plugins-monitor.log 2>&1 &
For persistent monitoring, wrap this in a systemd service — otherwise the process disappears after a reboot. AIDE gives a deeper check: it records a filesystem baseline and compares against it on every run. A new directory appearing in wp-content/plugins/ will be caught at the next check, even if the loader deleted itself long before:
# Initialize baseline on a clean system
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Check current state against baseline
aide --check
Run aide --check daily via a systemd timer — any deviation from baseline will appear in the report. For a WordPress server handling real transactions, this is not optional.
CONCLUSIONS
ShapedPlugin is not an isolated case. This is the second major supply chain incident in the WordPress ecosystem within a single month, following OptinMonster. The vector through build pipeline or distribution infrastructure is becoming a standard tool — it allows attackers to reach all of a vendor’s customers simultaneously, leveraging the trust those customers already place in the vendor.
The practical takeaway is straightforward: the WordPress Dashboard is not an authoritative source of information about what is actually installed on the server. A plugin can be absent from the list and still be running. AIDE on the filesystem, monitoring for new files in wp-content/plugins/, auditing via WP-CLI — this is not excessive caution. It is the baseline for any site handling real transactions.
The compromise window was approximately one month: May 21 to June 16. Fixed versions are available. If you ran any of the three Pro plugins during that period, treat your site as compromised and work from that assumption — not from the hope that you were not affected.
