When your plugin’s “Help & Support” button grants itself admin

Routine maintenance, nothing prompted it: you open the Application Passwords section of your own WordPress profile and find one you didn’t create. It’s labeled “WAP – Rank Math Support Agent.” No date attached to when it expires, because it doesn’t. You never approved it, because you were never asked. Closing the browser tab that must have created it didn’t revoke it. It’s just there, sitting in the same list as every application password you did generate, indistinguishable from them except for the name.

That’s what site owners running Rank Math found in late August 2026, after version 1.0.277 shipped a new “Help & Support” AI assistant on August 26, on a plugin installed on more than four million sites. As soon as an admin with a free Rank Math account opened that screen, the plugin generated an Administrator-level Application Password and sent it to servers run by group.one (Rank Math’s parent company, which also owns WP Rocket) so its support agent could act on the site directly. There was no consent screen before the credential existed. A Terms checkbox appeared, but only after the password had already been created and transmitted.

Rank Math shipped 1.0.277.1 the next day, August 27, but it fixed an unrelated notice bug, not the consent gap. Sybre Waaijer, who builds the competing SEO Framework plugin, disclosed the credential-creation issue publicly on X on August 28. It kept generating, unrevoked, for three more days after his post before Rank Math paused the Support Agent entirely in 1.0.277.2 on August 31. Users on the plugin’s own support forum reported that a large thread airing complaints about the feature had been deleted; Rank Math hasn’t confirmed why. When the company did address it, its own language conceded the real failure: “you should be told clearly and directly what is happening and what you’re allowing.” That sentence describes a consent screen that should have existed and didn’t.

Application Passwords were never built to be handed to a stranger

None of this required a vulnerability. WordPress Application Passwords have worked exactly as designed since they shipped in core in December 2020: a credential scoped to one application, individually revocable, that never touches the user’s login password. They were built for a script or a mobile app authenticating against the REST API, not for a human deciding on the spot whether to grant a stranger’s AI agent the same reach as their own admin account. The API shows the password once, in plaintext, for the calling code to store. It doesn’t ask permission first, because it was never built to be handed to a third party without the site owner initiating the request themselves.

That gap between the tool and how it’s now getting used is where every incident in this piece lives. A “Help & Support” button is a UI decision rather than an API one, and the plugin author chooses whether opening it triggers a disclosed, opt-in request or a silent one. Rank Math chose silent. That design decision is what the whole story turns on; the application-passwords feature did precisely what it was built to do.

WPForms reached for the same shortcut first

Rank Math wasn’t the first plugin this year to reach for Application Passwords as a support shortcut, and the earlier attempt shows the same pattern in how WordPress plugin teams are solving this problem.

WPForms Lite 2.0.0, released July 14, 2026, used a temporary admin token during its onboarding wizard to transfer new users to WPForms’ own servers and finish setup; the code is in the plugin’s SetupWizard/Bridge.php. Waaijer flagged this one too: “a one-hour master key is still a master key.” An hour is enough time for an admin-equivalent credential to install a plugin, since installing a plugin is how you execute arbitrary PHP on someone’s server. WPForms responded faster than Rank Math would five weeks later: builds 2.0.0.3 through 2.0.1 added a plain notice that the user was being handed to an external, WPForms-controlled site.

That’s a real difference: WPForms disclosed once it was caught, and fixed it inside a week. Rank Math didn’t disclose at all until a competitor’s developer forced the question, and took five days to stop minting the credential once he had. But a quicker apology isn’t the same as a fix. An hour-long master key and a permanent one are the same primitive with different clocks attached: in both, a company’s server decides when your admin session ends.

A third pattern belongs next to these two, and it arrives from the opposite direction: a credential that is already installed, under a new owner nobody voted on. In 2025, someone with an SEO and gambling-marketing background bought a portfolio of 31 WordPress plugins on Flippa, a six-figure deal that came with the seller’s existing commit access on WordPress.org. That August, a routine-looking update whose changelog read only “Check compatibility with WordPress version 6.8.2” added 191 lines of code implementing a deserialization backdoor. It sat inert for roughly eight months while more than 180,000 sites (adding up the install counts Patchstack published for the plugins it named) kept auto-updating on schedule, running the same plugin they’d installed under the previous owner. On April 5, 2026, it activated for six hours and forty-four minutes, serving spam invisible to anyone but Googlebot. WordPress.org’s Plugins Team closed all 31 plugins on April 7. Nobody who installed those plugins consented to a new owner either; the access transferred without a notice, the way a WordPress.org listing lets it.

The three incidents ran on different mechanisms (a silent credential grant, a time-boxed one, an inherited one) and share one shape: a company decided the site should have this access, and never asked the owner first. If you ship a plugin with a support feature in it, you are one design decision away from the same story.

Consent-first access needs four things at once

If you are the next plugin team building this screen, four things have to be true at once before a site owner can reason about the access you are asking for; three out of four is what Rank Math and WPForms each shipped.

It has to be visible before it exists, which rules out a checkbox that appears after the credential has already been created and sent somewhere, and a notice that shows up only once a researcher asks why. It has to be scoped to what the request is for: a support session answering one ticket doesn’t need the reach of a developer with an FTP account, and “Administrator” is almost never the honest answer. It has to expire on its own, on a timeline the site owner can see before agreeing to it. The Essential Plugin backdoor sat dormant for roughly eight months because nothing forced a decision point where trust had to be re-earned. And it has to be revocable in one click, from a screen the site owner controls, not a support ticket asking the vendor to turn it off.

This is the model TrustedLogin was built around, and the exchange itself is written out at how it works. For a plugin company it means the customer sees what they are agreeing to before anything is created, and the access ends on its own instead of waiting for someone to remember it. I built it because GravityKit hit this same problem five years ago and didn’t want to be the next company writing its own Application-Password bridge and hoping nobody looked too closely. It’s one way to build the request screen right. The point of this piece is that the screen has to exist at all, however a plugin author chooses to build it.

Asking first costs about a day of UI work

None of this needed to be adversarial to fix. A “Help & Support” button that asks first, before anything is created, in language a non-technical site owner can act on, costs a plugin team maybe a day of UI work more than the silent version does. Rank Math will presumably rebuild the Support Agent with that screen; its own postmortem language already describes it. WPForms already added its notice. The fix, in both cases, was the sentence Rank Math itself wrote after the fact: tell the person what’s happening and what they’re allowing, before you do it, not after someone else notices.

The next plugin that wants an AI agent inside a customer’s site has that sentence sitting in public now, next to two examples of what happens when it’s skipped. There’s no reason for a fourth incident to be the one that finally makes it stick.

Similar Posts