In October 2026 two WordPress vendors had to tell customers that a channel they trusted had been used against them. TeamUpdraft found unauthorised access to teamupdraft.com over the weekend of 17 and 18 October, and the data it believes was taken includes the connection keys for UpdraftCentral, its remote management service. A few days earlier, Rank Math PRO 3.0.123 went out with malware to people who downloaded it during a window of about eleven hours. The attackers did not need a weak password on any victim's site: they came in through connections the owners had approved, in some cases without knowing it.
This guide is for any business with a website or an online shop, whether it runs on WordPress, WooCommerce, Shopify or a custom stack. It shows how to list every service that holds a key to your site, how to revoke the keys nobody needs, when to rotate the rest and what to put in writing with vendors and agencies.
What happened in the UpdraftCentral breach
According to the TeamUpdraft incident notice, the company believes its customer database was accessed. That database holds names, email addresses, hashed passwords, two-factor settings and the connection keys for UpdraftCentral, UpdraftVault and UpdraftClone. Card data is handled by Stripe and PayPal and was not stored. The attacker used the connection to customer sites to create admin accounts and install malicious plugins, and TeamUpdraft later warned about a pattern of unexpected Editor accounts. UpdraftPlus 1.26.13 (free) and 2.26.13 (Premium), released on 19 October, disconnect every UpdraftCentral connection made before 13:07 BST on 18 October.
Patchstack’s analysis explains why ordinary defences did not help. The commands were signed with genuine dashboard keys, so every check in the plugin passed. A connected site runs any signed command with the permissions of the user who created the connection, and nobody confirms individual commands. Many owners never chose this: when you connected a TeamUpdraft.com account, a checkbox that added the site to UpdraftCentral was ticked by default. Keys also did not expire, and Patchstack saw keys issued in November 2025 still working in October 2026. The backdoor accounts looked like Editors while holding the manage_options and install_plugins capabilities, so a review of the administrator list missed them.
What happened with the Rank Math PRO download
Rank Math’s statement says that PRO 3.0.123 downloaded between 15 October 20:02 UTC and 16 October 07:12 UTC contained malware, and 3.0.124 is the clean release. The free version on WordPress.org was not affected. For sites that activated the bad build, Rank Math asks owners to assume that every secret on the site is exposed, and lists what to change: WordPress passwords, database credentials, the security keys and salts in wp-config.php, payment gateway keys, SMTP credentials, other API keys, hosting, FTP and SSH access, and two-factor settings for administrators.
That list is the best short description of what a website holds. Your site stores keys to other systems, and other systems store keys to your site. Both directions belong in the audit. My article on supply chain attacks in 2026 covers the wider pattern behind these incidents.
How to find which services can access your website
Collect the list from three places: the site itself (users, plugins or apps, settings), your company accounts (invoices, the password manager, the email inbox where signup confirmations land) and your infrastructure (DNS, CDN, hosting panel, code repository). For each entry write down the service, what it can do, who created the key, where the key lives on both ends, when it was last used and who in your company owns it. An entry without an owner is the first candidate for removal.
Remote management dashboards
UpdraftCentral, ManageWP, MainWP and Jetpack connect to a WordPress site through a component installed on it: UpdraftPlus carries the UpdraftCentral client, ManageWP uses the ManageWP Worker plugin and MainWP uses MainWP Child. The dashboard keeps its half of the credentials on the vendor’s servers or on a server your agency runs. Check the plugin list, including the must-use tab, and ask your agency which dashboards it uses on your site. Patchstack’s main lesson applies to every product of this type: removing the site from the dashboard is not enough, because the key that matters sits on the site.
Store apps and integrations with API access
On Shopify, open Settings, Apps and click each app. The Activity and permissions section on the app’s page shows which store areas it can view or edit and when it last used each of them. Permissions the app has not used in the last 30 days appear under Unused access, according to Shopify’s documentation. The read_all_orders scope extends an app’s reach beyond the default window of orders from the last 60 days (access scopes), so ask why an app needs it. Before you uninstall an app, export what you need: Shopify warns that some apps store data you cannot recover afterwards.
In WooCommerce the keys are under WooCommerce, Settings, Advanced, REST API. Each key is linked to a WordPress user and has Read, Write or Read/Write access, and the consumer secret is shown only once (WooCommerce REST API). Check which user every key belongs to and whether that person still works with you.
Application passwords and API users
WordPress application passwords let a tool log in to the REST API with Basic Auth. You create and revoke them on the Edit User screen. Core does not scope them yet: the integration guide lists scoping as future development, so an application password can do whatever its user can. WordPress records the last use (accurate to within 24 hours) and the last IP address. With WP-CLI:
wp user list --role=administrator
wp user list --role=editor
wp user application-password list 1 --fields=name,created,last_used,last_ipThe editor list matters after the UpdraftCentral case, because the backdoor accounts were Editors with extra capabilities.
CDN and DNS tokens
A token with DNS edit permission can point your domain or your mail records somewhere else. In Cloudflare, an API token is limited to chosen permissions and zones and can be restricted further with client IP filtering and a TTL (create a token). The older Global API key has access to all of a user’s resources with that user’s full permissions, and Cloudflare does not recommend it for new use (Global API key). If a plugin, a CI job or a cache purge script still uses the Global API key, replace it with a token scoped to one zone.
Deploy keys
A GitHub deploy key is an SSH key that grants access to a single repository. It is read-only by default, and with write access it can do what an organisation member with admin access can do. According to GitHub’s documentation, deploy keys have no expiry date, usually have no passphrase, and stay active when the person who added them is removed from the repository. Review them in the repository under Settings, Deploy keys, delete the ones you do not recognise and approve the valid ones.
Payment and email provider keys
Payment keys usually sit in the shop’s plugin settings or in environment variables. Stripe lets you create restricted keys with permissions you control, and when you rotate a key in the Dashboard you choose when the old one expires: “Now” deletes it at once, a later time gives the integration a window to switch (Stripe API keys). Email works the same way: an SMTP password or a transactional provider’s API key sits in a plugin or in wp-config.php. My SMTP guide shows where these settings live.
Backup services
A backup holds a full copy of the database, with customer data and every key stored in settings. TeamUpdraft disconnected all sites from UpdraftVault and issued new credentials. For sites accessed through UpdraftCentral it also recommended re-authorising remote storage such as Google Drive, Dropbox or Amazon S3 and changing the storage access keys. Check who can read your backup storage, and whether the backup tool’s credentials allow deleting old copies.
Invoicing and ERP system API keys
Update, . A WooCommerce plugin or Shopify app that issues invoices in an external system stores that system’s API key. In its incident notice, the Polish invoicing service Fakturownia stated that from 27 September 2026 (about 03:20) to 28 September 2026 (about 17:45) an unauthorised person had access to its systems and copied a large part of its database, including API tokens and integration keys stored in account settings. The incident affects every account. During the night of 28 to 29 September the company replaced customers’ API tokens, and the old keys have since worked only from IP addresses the account’s users had used before. Integrations configured in the “Integracje i dodatki” (integrations and add-ons) tab were not affected. For the others, Fakturownia recommends generating new keys and entering them in the integrations, and for third-party integrations, first agreeing with the provider on when to do it.
For customer data entered into the account, the business using Fakturownia is the controller and Fakturownia is the processor. The GDPR splits the duties as follows:
- the processor notifies the controller without undue delay after becoming aware of a breach (Article 33(2)); Fakturownia says its email to account owners, sent from 1 October 2026, is that notification,
- the controller notifies the supervisory authority (in the United Kingdom the ICO, under UK GDPR, which keeps the same 72-hour rule; in Ireland the Data Protection Commission) without undue delay and, where feasible, not later than 72 hours after becoming aware of the breach, unless the breach is unlikely to result in a risk to the rights and freedoms of natural persons; a notification made after 72 hours must be accompanied by reasons for the delay (Article 33(1)),
- when the breach is likely to result in a high risk to the rights and freedoms of natural persons, the controller communicates it to the data subjects without undue delay (Article 34(1)),
- the controller documents every breach, including those not notified (Article 33(5)).
In the United Kingdom, the ICO’s breach reporting guidance says that if a risk is likely you must notify it as soon as possible and, where feasible, within 72 hours, and Article 33 of UK GDPR requires you to document every breach as well. In Ireland, the Data Protection Commission takes notifications only through its Breach Notification Form and expects an internal record even when you conclude there is no risk, including how and by whom that decision was made and the risk rating you gave.
During the audit, replace the invoicing system’s key after any vendor incident notice and check whether the key can be restricted to your shop server’s IP address. Fakturownia applied that kind of restriction to the old keys after the incident.
Website access audit checklist
| Service type | Where the key lives | How to revoke | Rotate when |
|---|---|---|---|
| Remote management dashboard (UpdraftCentral, ManageWP, MainWP, Jetpack) | Connector plugin settings on the site, plus the vendor’s or agency’s dashboard | Delete the key on the site first, then remove the site from the dashboard | Vendor incident, agency change, dashboard no longer used |
| Shopify app | The app’s grant in Settings, Apps | Export data, then uninstall the app | Unused access listed, vendor incident, app no longer needed |
| WooCommerce REST API key | WooCommerce, Settings, Advanced, REST API, tied to a WordPress user | Revoke link next to the key | The linked user leaves, the integration is replaced |
| WordPress application password | The user’s profile, hashed in user meta | Revoke on the Edit User screen or with WP-CLI | No use since the last audit, the user leaves, site compromise |
| CDN or DNS token (Cloudflare) | Cloudflare account and the tool that calls the API | Delete the token in the Cloudflare profile | Token seen in a log or repository, person or tool leaves; roll for a new secret |
| Deploy key (GitHub) | Private key on the server, public key in repository settings | Delete under Settings, Deploy keys | Server rebuilt or compromised, agency change |
| Payment key (Stripe and other gateways) | Shop plugin settings or environment variables | Rotate with an expiration time, then confirm the old key is gone | Site compromise, developer access ends |
| Invoicing or ERP system key | Shop plugin settings and the invoicing system account | Generate a new key in the invoicing system and replace it in the shop | Vendor incident (e.g. Fakturownia, September 2026), system change |
| Email or SMTP key | SMTP plugin settings, wp-config.php, environment variables | Delete the key at the email provider | Site compromise, plugin or provider change |
| Backup storage credentials | Backup plugin settings and the storage provider’s access settings | Revoke at the storage provider and re-authorise | Vendor incident, site compromise |
How to revoke an API key without breaking the site
On a healthy site, work in this order. Find what uses the key: its description, last use and the logs of the tool that calls it. Create the replacement with narrower permissions where the platform allows it. Put the new key into the consuming tool and confirm it works. Revoke the old key and watch for a few days for failed orders, missing emails and broken deployments. Stripe’s expiration window exists for exactly this switch.
On a compromised site, reverse the order: revoke first and accept that some integrations will stop until you reconnect them. TeamUpdraft’s instructions for UpdraftCentral users follow that logic: log in to each site directly, update, delete the connection key, remove unknown accounts and plugins, change admin passwords and only then reconnect. Revoke on both ends whenever there are two. A key deleted only in the vendor’s panel can still be accepted by the site, and a key deleted only on the site can still sit in the vendor’s database.
When to rotate API keys
Rotate on events, because a calendar alone would not have helped anyone in October 2026. The triggers worth writing into your procedures:
- a security incident at a vendor that holds a key to your site or receives one from it,
- malicious code that ran on your site, which means everything on Rank Math’s list above,
- a person, freelancer or agency losing access,
- a key found where it should not be: a repository, a support ticket, an email thread or a screenshot,
- an integration replaced by another tool.
Add one fixed review a year on top of that, and delete every key nobody can explain. Keys without an expiry date, like GitHub deploy keys or the UpdraftCentral keys Patchstack examined, stay valid until someone removes them.
How to rotate API keys on each platform
The order described above holds everywhere, but each platform has its own switches. These are the steps from the vendors’ documentation as of October 2026.
Stripe secret and restricted keys
- On the API keys page, open the menu next to the key and choose View request logs. Workbench opens and shows which systems still call Stripe with that key.
- Choose Rotate key and set an expiry time for the old key. According to Stripe’s documentation, the old and new keys can both work for up to 7 days after a rotation in the Dashboard. If you need longer, create a new key manually and expire the old one when the switch is done.
- Put the new key into the shop or server, then open the old key’s request logs again. Stripe advises letting the old key expire only after its request volume has stayed at zero for some hours or days.
- Assign an access policy to every live key. A policy limits a key to IPv4 addresses or CIDR ranges or, for servers that scale dynamically, to an ASN and a country, and it can block anonymous VPNs, public proxies and Tor exit nodes. Stripe blocks requests that break the policy and notifies you.
Stripe recommends restricted keys (rk_) for most integrations and no longer recommends unrestricted secret keys for new ones. Webhook signing secrets are separate from API keys and sit under each webhook endpoint, so rotating an API key leaves them unchanged.
Cloudflare API tokens
When you create the replacement token, fill in the two optional fields most owners skip. Client IP address filtering: without a rule, any IP address can use the token; an Is in rule limits it to the listed addresses or CIDR ranges, and Is not in exempts specific addresses from a range. TTL: a start date (notBefore) and an end date (notAfter). A token without an end date never expires, and the dates count from 00:00 UTC on the chosen day (restricting tokens). A cache purge token tied to your server’s fixed IP address, with an end date at your next annual review, is a sensible default.
Shopify app credentials
Since 1 January 2026, Shopify custom apps are created and managed in the Dev Dashboard, and custom apps created in the admin before that date are still managed in the admin as legacy apps (custom apps). That split decides how you rotate. According to Shopify’s rotation guide, a Dev Dashboard app gets a new client secret under Settings, Credentials, Rotate, and the old secret keeps working until you revoke it. Shopify keeps signing webhooks with the oldest unrevoked secret, so the app has to accept both signatures during the switch. Tokens obtained with client credentials last 24 hours. Revoke the old secret only after every stored access token has been replaced, because tokens pinned to it stop working at that moment. A legacy custom app created in the admin cannot rotate its secret: to change its credentials, the merchant uninstalls and reinstalls the app. If a secret is being misused right now, Shopify says to revoke it first and accept that the app stops until the new secret is in place.
GitHub tokens and deploy keys
A fine-grained personal access token reaches the resources of one user or one organisation and can be limited to selected repositories. Its expiry is set between 1 and 366 days or to none, the default is 30 days, and an organisation policy can forbid tokens that never expire. GitHub removes personal access tokens that have not been used for a year (managing tokens).
Two details change how you clean up. Deleting a token that was used to create a deploy key deletes that deploy key as well, so check the repository’s deploy keys before you remove someone’s tokens. And organisation owners can see and revoke fine-grained tokens with access to the organisation, but not classic tokens: unless the organisation restricts them, a classic token keeps access to organisation resources until it expires (reviewing tokens in an organisation).
WooCommerce REST API keys
WooCommerce has no roll button. Create a new key with a description that names the integration, assign it to a dedicated user, choose the narrowest permission (Read covers reporting and accounting exports), copy the consumer secret because it is shown only once, update the integration and then revoke the old key.
What to revoke when an employee or agency leaves
Work through this list on the day access ends:
- WordPress. Delete the person’s application passwords, end their logged-in sessions, then delete the account and hand their posts to another user (WP-CLI user commands):
wp user application-password delete 123 --all
wp user session destroy 123 --all
wp user delete 123 --reassign=2- WooCommerce. Revoke every REST API key linked to that user and recreate the ones an integration still needs under a dedicated account.
- Shopify. Remove the staff or collaborator account and review the apps it installed. Building custom apps requires the App development, Develop permission, and collaborator accounts cannot use the Dev Dashboard, so check who held that permission and which apps they created.
- Cloudflare. Delete the tokens the person created, or roll the ones an integration still needs. Then read the Audit Logs page for the period they had access; Cloudflare keeps those entries for 18 months (audit logs).
- GitHub. Remove the person from the repository or organisation, delete the deploy keys on servers they set up and revoke their fine-grained tokens in the organisation settings. GitHub emails the creator when a token is revoked, and SSH keys created by a revoked token keep working, so delete those separately.
- Stripe. Rotate every secret or restricted key the person could see. Stripe lists a team member leaving or changing roles as a reason to rotate.
- Remote management and backups. Delete the connection key on each site, as described for UpdraftCentral above, and re-authorise remote backup storage.
Where key use is logged
| Platform | What it records | Alert |
|---|---|---|
| WordPress | Last use (accurate to within 24 hours) and last IP address of each application password | None documented in core |
| Stripe | Request logs for each key in Workbench | Notification when an access policy blocks a request |
| Cloudflare | Audit Logs of account and zone changes, kept for 18 months | Not described on the audit log page |
| GitHub | Fine-grained tokens with access to the organisation, visible to its owners | Email to the token creator when an owner revokes it |
| Shopify | Last use of each permission on the app page, unused access after 30 days | None documented |
For a small business the practical routine is to read these five screens during the annual review and after every trigger listed earlier. Stripe’s access policies are the one place on this list that alerts you on its own, which is a reason to set them up first.
What to require from your agency and software vendors
An agency that maintains your site creates keys in your name. Put these points in the contract or the maintenance scope:
- A register of every key, token and account the agency creates, with purpose and owner, handed over on request and at the end of the contract.
- Keys created in your accounts where the platform allows it, for example a Cloudflare token in your Cloudflare account scoped to your zone, so revoking it does not depend on the agency.
- One key per site and per tool, and named user accounts instead of a shared “agency” login.
- Revocation of all access within an agreed number of days after the contract ends, confirmed in writing.
- A notice deadline for incidents. Under Article 33 GDPR a processor has to notify the controller without undue delay, and the controller has 72 hours, where feasible, to notify the supervisory authority. Write a concrete number of hours into the contract so nobody argues about “undue”.
Before you install anything with remote features, ask the vendor whether the remote connection is switched on by default and whether its keys expire. For UpdraftCentral, Patchstack’s answers were yes and no.
I run this audit as part of a WordPress security audit and keep the register current in website maintenance. For WooCommerce shops it is part of the store reliability plan, and for Shopify stores I review app permissions as part of Shopify development. If you want to see how plugin updates reach your site and where a tampered release could slip in, read about the WordPress.org 24-hour update delay and four plugin backdoors in one month.







