Skip to content

Security10 min read

cPGuard supply chain attack: check your server and WordPress sites

Check for the cPGuard supply chain attack on your server, identify malicious updates, rotate exposed credentials and secure every hosted WordPress site.

Portrait of Hamza Ahmad AslamBy AI & WordPress Developer | Speed Optimization & Site Security

Conveyor of sealed update parcels where one cracked parcel sends violet tendrils toward keys stored in a server rack
Illustration generated with Gemini
On this page
  1. What happened in the cPGuard supply chain attack?
  2. How do you check if your cPGuard update was compromised?
  3. Check the installed version
  4. Check the installation history
  5. Check the files left by the attack
  6. Which credentials must you rotate, and in what order?
  7. 1. Change root and local account passwords
  8. 2. Replace root SSH keys
  9. 3. Rotate MySQL credentials
  10. 4. Replace cloud credentials and shell-history secrets
  11. 5. Secure the OPSSHIELD billing account
  12. What should you check on every WordPress site?
  13. Change each site's database password
  14. Regenerate the WordPress salts
  15. Review WordPress administrator accounts
  16. Verify WordPress core and plugin files
  17. Reset SFTP, FTP and stored API credentials
  18. Copyable server and WordPress recovery checklist
  19. When do you need to rebuild the server?
  20. What remains unknown as of November 7, 2026?
  21. What should you do next?
  22. Frequently asked questions

The cPGuard supply chain attack put root-level server credentials at risk through a malicious automatic update on November 2, 2026. Check your cPGuard update history first, even if you have already patched the server. If an affected update was installed, rotate the exposed credentials and check every WordPress site hosted there.

What happened in the cPGuard supply chain attack?

An attacker broke into OPSSHIELD's billing and licensing infrastructure, obtained an update-storage key and published fake cPGuard updates.

According to OPSSHIELD's November 3 incident disclosure (opens in a new tab), the attacker uploaded the updates between 02:04 and 02:09 UTC on November 2, 2026. cPGuard agents installed them between approximately 02:08 and 03:20 UTC.

The affected updates were versions 5.88.12 through 5.88.19. The malicious script ran with root privileges, giving it access to sensitive server files.

OPSSHIELD reported the following figures on November 3:

  • About 2,950 customer servers ran the fake update.
  • About 7,900 billing-portal accounts had their names, company details, postal addresses, email addresses and bcrypt-hashed passwords exposed.
  • The script collected /etc/shadow, /etc/passwd, root SSH files, MySQL credentials where present and root shell history.
  • On a small number of servers, it also collected cloud storage credentials from /root/.s3cfg.

The script sent collected data through OPSSHIELD's compromised licensing system for the attacker to retrieve. The vendor's earlier advisory estimated that the attacker retrieved 32 collected files, each associated with a customer server. That preliminary figure does not limit the number of potentially affected servers.

The attacker also left a hidden root shell and files used by a scheduled task.

The wider OPSSHIELD breach (opens in a new tab) matters to WordPress administrators because root-level access can expose the database credentials, configuration files and website data belonging to every hosting account on that machine.

How do you check if your cPGuard update was compromised?

Check the installed version

Connect using your hosting provider's trusted management console or a known-safe administrative session.

Run:

cpgcli --version

OPSSHIELD instructs administrators to install version 5.88.25 or later. If your server is below that version, run the vendor's documented update command:

cpgcli update --start

This changes the installed software. Preserve relevant evidence first, then verify the version again.

The two vendor notices describe the corrective releases differently. The advisory says 5.88.25 or later removes the known backdoor and staged files. The later disclosure names 5.88.26 as the clean update that removes the hidden root shell, with another update removing the scheduled task.

Treat 5.88.25 as the minimum, as the advisory directs. Install the latest available corrected release.

Check the installation history

Run:

grep 'Successfully updated' /opt/cpguard/logs/install_log

Look for any entry showing version 5.88.12 through 5.88.19.

A matching entry establishes that the server installed an affected update. Treat it as potentially compromised even if the installed version is now 5.88.25 or later.

An installation entry alone does not prove script execution or data transfer. A missing entry is also inconclusive because logs may be incomplete or removed.

If you can establish that cPGuard was offline and did not check in during the affected window, the vendor says it did not receive the fake update. Otherwise, contact OPSSHIELD for help checking its incident records.

Check the files left by the attack

OPSSHIELD lists these customer-server indicators:

  • /etc/cron.d/i93677: the scheduled task.
  • /var/tmp/.i93677/: files associated with that task.
  • /var/tmp/.cpg91511_sh: a hidden setuid-root shell, which can run with its owner's privileges.
  • /var/tmp/.cpg91511/: a collection directory named in the earlier advisory, including /var/tmp/.cpg91511/loot.tgz.

The disclosure also names 94.183.188.91 as the attacker's main operator IP address. Check historical firewall, authentication and network logs for connections involving it. Compare matches with the surrounding activity.

Use this read-only check for the known paths and update history:

#!/usr/bin/env bash

for path in \
  /etc/cron.d/i93677 \
  /var/tmp/.i93677/ \
  /var/tmp/.cpg91511_sh \
  /var/tmp/.cpg91511/
do
  if [ -e "$path" ] || [ -L "$path" ]; then
    printf 'FOUND: %s\n' "$path"
  else
    printf 'NOT FOUND: %s\n' "$path"
  fi
done

log=/opt/cpguard/logs/install_log

if [ -r "$log" ]; then
  printf '\nSuccessful update entries:\n'
  grep 'Successfully updated' "$log" ||
    printf 'No matching entries in readable log\n'
else
  printf '\nInstall log missing or unreadable: %s\n' "$log"
fi

The script reports path existence and prints successful update entries for review. It does not remove files or change configuration.

Missing indicators do not clear the server. Corrective updates remove known attack files, and an attacker may have deleted evidence.

If an indicator remains, preserve its details before removing it. OPSSHIELD directs administrators to delete known malicious files after updating, but removal should be deliberate. Have an incident responder handle evidence preservation if needed.

Which credentials must you rotate, and in what order?

Perform these steps from a trusted machine or recovery environment. Confirm replacement access before revoking old credentials, so you do not lock yourself out.

1. Change root and local account passwords

Reset the root password and passwords for all password-enabled local Linux accounts.

The attacker targeted /etc/shadow, which stores password hashes rather than plaintext passwords. Common or reused passwords may still be guessed offline.

Change reused passwords on other systems from a trusted device.

2. Replace root SSH keys

Treat private keys under /root/.ssh as exposed.

Generate replacements in a trusted environment and verify that the new keys work. Remove the old public keys from authorized_keys on every server that trusted them.

Review authorized keys for unfamiliar entries. Check backup hosts, staging machines and other production servers reachable with the old keys.

Replacing a private key does not revoke it until receiving servers stop trusting the corresponding public key.

3. Rotate MySQL credentials

Change the MySQL or MariaDB root password and any other database passwords stored in /root/.my.cnf.

Update backup jobs, management tools and scripts that depend on those credentials. Test their connections before retiring old access.

A stolen MySQL root password can expose every WordPress database that account can access. Treat those databases as potentially readable and writable.

4. Replace cloud credentials and shell-history secrets

Rotate keys stored in /root/.s3cfg and other cloud credentials found in the affected root account.

Review root shell history for passwords, deployment tokens and API keys typed directly into commands.

Revoke old credentials at their issuing services. Editing shell history does not invalidate a stolen token.

5. Secure the OPSSHIELD billing account

Reset the password for manage.opsshield.com and enable two-factor authentication.

Do this even if your server was offline during the attack window. The billing-portal account exposure was separate from the malicious updates.

What should you check on every WordPress site?

If the server installed an affected update, review every hosted WordPress installation.

With MySQL root access, an attacker may be able to read or change WordPress users, options, posts and other stored information. That exposure does not establish that a particular database was modified.

Change each site's database password

Identify the database account used by each WordPress installation.

Change its password on the database server, then update DB_PASSWORD in wp-config.php.

For a conventional configuration, the setting looks like this:

define( 'DB_PASSWORD', 'REPLACEMENT_SECRET' );

REPLACEMENT_SECRET is an illustrative placeholder, not a password to use.

Keep the existing database name, username and host unless they also need changing. Use the hosting panel's password-change feature if it manages database accounts.

Test the website immediately afterward. A password mismatch can stop WordPress from connecting to its database. Also update scripts or deployment systems using that account.

Regenerate the WordPress salts

WordPress salts are secret values used in its authentication system. Replacing them helps invalidate existing login sessions.

From each WordPress installation directory, run:

wp config shuffle-salts

This write operation modifies wp-config.php. The command is documented in the WP-CLI salt rotation reference (opens in a new tab).

Back up the configuration first and tell administrators they will need to sign in again. Changing salts does not change user passwords or database credentials.

Review WordPress administrator accounts

Run:

wp user list --role=administrator

The WP-CLI user listing documentation (opens in a new tab) confirms that --role filters users by role.

Compare the results with approved administrators. Investigate unfamiliar usernames, email addresses and registration dates before removing accounts.

For a wider review, follow the procedure for finding and removing hidden WordPress administrator accounts.

Review existing audit logs for account changes. A clean administrator list cannot rule out direct database changes.

Verify WordPress core and plugin files

Run these checks from each installation directory:

wp core verify-checksums
wp plugin verify-checksums --all

The first command compares core files with official WordPress checksums. The second checks eligible plugins against WordPress.org checksums, as documented in the WP-CLI plugin checksum reference (opens in a new tab).

These commands do not replace files. Investigate unexpected mismatches.

Custom plugins, premium plugins and modified distributions may lack matching WordPress.org checksums. Compare those files with trusted releases or your source repository.

For the separate risk of malicious extension updates, see how WordPress plugin supply chain attacks work.

Reset SFTP, FTP and stored API credentials

Reset credentials that can upload or modify website files. Include hosting-panel users, SFTP and FTP accounts, deployment credentials and automation accounts.

Review secrets stored in wp-config.php and the WordPress options table, including payment, email, backup and external API credentials.

Revoke exposed keys at their issuing services, then update WordPress integrations. Use each plugin's supported settings screen rather than editing serialized database values manually.

Copyable server and WordPress recovery checklist

Use this table as a working record. Complete server recovery before putting replacement secrets into hosted WordPress installations.

StepCommand or placeWhat a bad result looks likeWhat to do
1. Preserve evidenceHosting console, cPGuard logsLogs may be lost during cleanupPreserve available logs securely
2. Check versioncpgcli --versionVersion below 5.88.25Run cpgcli update --start, then verify
3. Check update historygrep 'Successfully updated' /opt/cpguard/logs/install_logVersion 5.88.12 through 5.88.19Treat root secrets as exposed
4. Check scheduled task/etc/cron.d/i93677Path existsPreserve evidence, then remove the malicious task
5. Check task files/var/tmp/.i93677/Directory existsPreserve and remove known malicious files
6. Check hidden shell/var/tmp/.cpg91511_shFile existsEscalate, preserve evidence and remove through a trusted environment
7. Check collection files/var/tmp/.cpg91511/Directory or loot.tgz existsPreserve and remove known collection files
8. Check attacker addressNetwork and authentication logs, 94.183.188.91Unexplained connection or loginInvestigate related activity
9. Reset local passwordsRoot and Linux usersOld passwords still workReset from trusted access
10. Replace SSH keys/root/.ssh, remote authorized_keysOld keys still authorize accessReplace keys and revoke old trust
11. Rotate database credentialsMySQL root, /root/.my.cnfOld credentials remain usableRotate and update dependent tools
12. Rotate cloud keys/root/.s3cfg, cloud accountsOld keys remain activeRevoke and replace them
13. Review shell secretsRoot shell historyPassword or token appearsRevoke the exposed secret
14. Secure billing loginOPSSHIELD portalOld password or unprotected loginReset password and enable 2FA
15. Rotate site database usersDatabase panel, wp-config.phpOld WordPress DB password worksChange database user password and DB_PASSWORD
16. Refresh WordPress saltswp config shuffle-saltsOld authentication secrets remainRegenerate salts on each site
17. Review administratorswp user list --role=administratorUnrecognized administratorInvestigate and revoke unauthorized access
18. Verify corewp core verify-checksumsUnexpected mismatchCompare with a trusted release
19. Verify pluginswp plugin verify-checksums --allUnexpected mismatch or unverified codeCheck trusted plugin sources
20. Reset file accessHosting panel, SFTP and FTP usersOld credentials remain activeRotate and revoke old access
21. Rotate application secretswp-config.php, options tableExposed API key remains activeRevoke and replace at the issuing service
22. Review login evidence/var/log/secure or /var/log/auth.logUnknown root login or sudo activityEscalate for incident response and rebuild assessment

Keep a separate completion record for each hosting account and WordPress site. Record the replacement date and responsible administrator without writing passwords into the worksheet.

When do you need to rebuild the server?

OPSSHIELD does not recommend a full operating-system rebuild as the routine response to the known malicious update.

Its November 3 disclosure recommends rebuilding from a clean backup taken before November 1 when the vendor has confirmed that the attacker manually logged in to your server.

Check available authentication logs, commonly /var/log/secure or /var/log/auth.log, for successful root logins, unexplained sudo sessions and administrative activity from unknown IP addresses.

A failed login attempt alone does not prove access. Compare successful logins with known administrator activity.

If manual attacker access is confirmed, additional compromise is discovered or you cannot establish server integrity, contact a qualified incident responder. A rebuild may be necessary.

Have the responder assess backup integrity and retained credentials before restoration. Preserve evidence before deleting files or rebuilding.

What remains unknown as of November 7, 2026?

The two OPSSHIELD notices leave several questions open.

The vendor traced the attack to its billing application but says its logs did not capture the exact request that allowed command execution. It patched two possible entry points.

The advisory identifies 5.88.12 through 5.88.19 as affected. It does not establish whether versions 5.88.20 through 5.88.24 contained the same malicious code.

The full scope of credential retrieval from individual servers remains uncertain. Published indicators may also be incomplete.

Neither notice reports confirmed changes to customer WordPress websites or databases. Undetected changes remain possible.

What should you do next?

Start with the installation log. If an affected update appears, preserve evidence, install the corrected release and rotate root-level credentials before updating WordPress secrets.

Work through each hosted site separately. Prioritize administrative access, database credentials, file-transfer accounts and integrations that can move data or money.

If you find unexplained file changes, unauthorized accounts or other signs of website compromise, use a qualified responder or WordPress malware removal support for application-level investigation. Suspected root-level compromise also requires an operating-system assessment.

Frequently asked questions

Was my server affected if cPGuard is now on 5.88.25?

It may have installed an affected update before reaching 5.88.25. Check /opt/cpguard/logs/install_log for successful installations of versions 5.88.12 through 5.88.19. An affected installation warrants credential rotation even after malicious files are removed.

Do I need to rebuild my server after the cPGuard malicious update?

OPSSHIELD does not recommend rebuilding every affected server as a routine response. Its disclosure recommends a clean pre-November 1 backup when manual attacker access is confirmed. Seek an incident responder's assessment if you find additional compromise or cannot establish server integrity.

Are my WordPress sites hacked if cPGuard was compromised?

The malicious update exposed credentials with access to server resources, including database credentials where present. This puts hosted WordPress sites at risk, but does not prove their files or databases were modified. Rotate their secrets and investigate account, database and file changes.

Do I need to change WordPress customer passwords?

The reported script collected server credentials, not a confirmed dump of WordPress customer password records. However, exposed MySQL root credentials may allow access to customer password hashes and other site data. Have a qualified incident responder assess the evidence and whether customer password resets are necessary, especially if database access or modification is suspected.

Can I trust a clean cPGuard scan after updating?

A clean scan can indicate that the known files are absent now. It cannot prove that credentials were never copied or used. Review the historical installation log and complete the necessary rotations independently of the scan result.

How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing.

Message

Ask me about your site

Tell me what is wrong or what you need built. I reply by email.

Prefer email? info@hamzaahmadaslam.com

Enjoyed this? Get the next article by email.

Occasional, useful posts. No spam, and you can unsubscribe anytime.

  • Brass padlock re-keyed with a glowing key on a server cabinet while keys and envelopes slip out of an open drawerSecurity

    11 min read

    DreamHost data breach: what to check on your WordPress site now

    The DreamHost data breach exposed FTP/SFTP credentials and some webmail accounts, putting affected WordPress sites at risk of unauthorized changes. Start by checking DreamHost's reset notice and securing your file-access and email accounts.

    • Security
    • WordPress
    • Incident Response
    Read article
  • A glowing contact form sends a violet beam into a stack of server files, one folder crumbling while a robotic arm returns a backup folder from a vaultSecurity

    12 min read

    Ultra Addons for Contact Form 7 vulnerability: check, update and recover

    The Ultra Addons for Contact Form 7 vulnerability (CVE-2026-102435) affects plugin versions 3.5.54 and earlier when PDF Generator is enabled and a form uses it. Version 3.5.55 fixes the flaw. Check your installed version and PDF Generator settings first, then update and look for signs of deleted files.

    • WordPress
    • Security
    • Plugins
    Read article
  • Server cabinet with its update vault briefly open under an hourglass, probe drones closing in as a shield gate slides shutSecurity

    13 min read

    WordPress 7.1.4 security release: exploited updater flaw and what to do now

    The WordPress 7.1.4 security release fixes 22 vulnerabilities, including an updater flaw that needs no login and can lead to remote code execution. Wordfence recorded attack attempts, and on November 3, 2026, CISA added the flaw to its Known Exploited Vulnerabilities catalog based on evidence of active exploitation.

    • Security
    • WordPress
    • Incident Response
    Read article