10 min read

A critical security vulnerability has recently been discovered in the Tutor LMS Pro plugin for WordPress, identified as CVE-2026-0953 with a CVSS score of 9.8 (critical). This flaw allows attackers to log in to any account on a website without requiring a password, including administrator accounts. It is estimated that more than 30,000 websites are currently using this plugin, and all of them are potentially at risk if they have not yet updated to the latest patched version.
Why did this vulnerability occur in Tutor LMS Pro?Link to heading

To better understand the CVE-2026-0953 vulnerability, it is important to first examine how social login mechanisms typically operate under the OAuth standard in a normal context.
When a user clicks “Log in with Google”, the standard flow is as follows:
- The website redirects the user to Google for authentication.
- Google verifies the user’s identity and returns an access token, which is a time-limited authentication code.
- The website uses that token to call Google’s API and retrieve the user’s information, including the email address verified by Google.
- The website compares that email address with its internal database and logs the user in.
The key point in this entire process is that the email must come from Google, not be entered manually by the user. Tutor LMS Pro failed to follow this basic principle.
>>> Learn more: What is privilege escalation? how privilege escalation works
Technical analysisLink to heading
Where the problem occursLink to heading
The entire social login flow is handled by the authenticate() function in the TutorPro\SocialLogin\Authentication class. Let’s break it down step by step to understand it more clearly:
Step 1: Reading data from the user request
$request = Input::sanitize_array(
wp_unslash( $_POST ),
array(
'email' => 'sanitize_email',
'profile_url' => 'sanitize_url',
)
);
Right from the start, the plugin takes the email directly from POST data submitted by the browser (or by anyone else). sanitize_email() only cleans up the email format; it does not verify whether that email actually belongs to the person trying to log in.
Step 2: Verifying the token from Google/Facebook
if ( 'google' === $auth_provider ) {
$verification = self::verify_google_token( $token );
if ( ! $verification ) {
wp_send_json_error( 'Invalid login request' );
}
$client_id = tutor_utils()->get_option( 'google_client_ID' );
if ( ! $client_id === $request['auth_id_token'] ) {
wp_send_json_error( 'Invalid Client ID', 'tutor-pro' );
}
}
This step is performed correctly: the token is verified with Google, and if the token is invalid, the request is rejected. However, the result returned by verify_google_token() - including the email address verified by Google, is completely ignored in the later steps.
There is also a small but important logic error in the Client ID check:
if ( ! $client_id === $request['auth_id_token'] )
In PHP, the ! operator has higher precedence than ===, so this line is actually evaluated as:
if ( (!$client_id) === $request['auth_id_token'] )
In other words, it compares a boolean value (false or true) with a token string. This comparison will almost always return false, which means the Client ID check is effectively useless.
Step 3: Using the email declared by the user
$email = $request['email'];
// Validate emails.
if ( empty( $email ) || ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
wp_send_json_error( __( 'Invalid email', 'tutor-pro' ) );
}
// User already exists.
if ( email_exists( $email ) ) {
$userdata = get_user_by( 'email', $email );
if ( is_a( $userdata, 'WP_User' ) ) {
$is_error = self::logged_in( $userdata );
}
}
This is the most dangerous part of the code. After the token has been verified, the plugin takes the email from $request['email'] - that is, data submitted by the user, and logs in to the account associated with that email without comparing it with the information from the token.
In short, the plugin’s actual logic is:
“Is this token valid? Yes. Then log in to the account with the email address [the email the user entered].”
Instead of:
“Is this token valid? Yes. What email address is inside the token? Log in to the account with that email address.”
Real-world attack scenarioLink to heading

With the CVE-2026-0953 vulnerability, an attack can typically unfold through the following steps:
First, the attacker has a normal Google account of their own. They sign in to Google and obtain an “access token”, essentially a credential that proves, “Google has just verified me as a legitimate user.” Everything is normal and fully legitimate at this stage.
Second, they need to know the email address of an admin account on the target website. This information is often not difficult to find, it may be publicly available on the contact page, in an author bio, or through WHOIS domain lookup tools.
Third, they submit a login request to the website, attaching their valid token but entering the victim’s email address in the email field, for example: admin@victim-website.com.
At this point, the plugin verifies the token and finds that it is valid. It then looks at the email that was submitted, finds the corresponding admin account in the database, and logs the attacker in. The attacker gains access to the admin dashboard without knowing any password at all.
What makes this even more concerning is that the entire process does not require programming skills. A simple HTTP request tool, something almost anyone working in web development has used before, is enough to carry out the attack from start to finish.
>>> Learn more: The truth about attacks bypassing two-factor authentication
What is special about the patch?Link to heading
The developer fixed the issue by adding an extra validation step during email verification:
Before the patch (vulnerable):
if ( empty( $email ) || ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
wp_send_json_error( __( 'Invalid email', 'tutor-pro' ) );
}
After the patch (safer):
if ( empty( $email ) || $verification->email !== $email || ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
wp_send_json_error( __( 'Invalid email', 'tutor-pro' ) );
}
The added condition $verification->email !== $email ensures that the email submitted by the user must match the email confirmed by Google or Facebook in the OAuth token. If the two do not match, the request is rejected immediately.
This is the correct approach that should have been implemented from the beginning: identity data must always come from a trusted source (the OAuth provider), never from user input.
Recommendations for administratorsLink to heading

Update the plugin immediatelyLink to heading
Go to WordPress Dashboard → Plugins → Installed Plugins, find Tutor LMS Pro, and check the current version. If it is lower than 3.9.6, update it right away.
If your website has automatic plugin updates enabled, make sure the update was actually applied. In some cases, the feature may be disabled because of conflicts with certain hosting configurations or security plugins.
After updating, open Settings → Social Login in Tutor LMS Pro and verify the Google/Facebook connection settings to make sure no unusual changes were made beforehand.
Check for signs of compromiseLink to heading
If your website has been running an older version for some time, do not simply update and move on. You should verify whether someone may have exploited the vulnerability already.
Check login history: Many security plugins such as Wordfence or WP Activity Log record login history along with IP addresses. Look for suspicious activity such as admin logins from unfamiliar IPs, other countries, or unusual working hours. If you do not already have a logging plugin installed, now is the time to add one.
Check admin accounts: Go to Users → All Users, filter by the Administrator role, and review the list carefully. If you see any unfamiliar admin account, even if the name looks ordinary, delete it immediately and change the passwords for all remaining admin accounts.
Check system files: Once an attacker gains access to the admin dashboard, the first things they often do are install malicious plugins or inject code into existing theme/plugin files. Review the list of active plugins, and if possible, compare WordPress core file checksums against the official release using wp core verify-checksums if you use WP-CLI.
Check server access logs: If you have access to server logs (usually located in /var/log/apache2/ or /var/log/nginx/), search for suspicious POST requests sent to the Social Login endpoint, especially requests coming from multiple IPs but targeting the same email address.
Temporarily disable Social Login if you cannot update immediatelyLink to heading
If, for any reason, you cannot update the plugin right away, the safest temporary measure is to disable the Social Login feature until the update is complete.
Go to the Tutor LMS Pro settings and deactivate the Social Login add-on. Users will still be able to log in with their normal username and password, so this will not completely disrupt the website’s operation.
W7SFW – An external protection layer that keeps your website safe even before the plugin is patched
W7SFW works as an independent external firewall, filtering and blocking malicious requests before they ever reach your website. This means attack scenarios such as fake login requests or plugin exploitation can be stopped at an early stage.
Its main strengths are simplicity and stability, no code changes required, no reliance on internal plugins, and no worry about conflicts when WordPress updates. Deployment is fast and does not require complex configuration, yet it still provides a full range of security protections. More importantly, W7SFW also includes features such as 2FA, SSL, free HTTP/3, and many other useful tools to help protect your website comprehensively.
Install W7SFW for your website today!
Strengthen admin account securityLink to heading

Even after patching the vulnerability, you should reinforce your administrative account protection.
Enable two-factor authentication (2FA): Even if an attacker obtains a password or exploits a similar vulnerability in the future, 2FA serves as the final barrier preventing them from completing the login. Plugins such as WP 2FA or Google Authenticator integrate well with WordPress.
Change admin passwords regularly: Use long, random passwords and never reuse them across multiple services. A password manager such as Bitwarden or 1Password can make this much easier.
Restrict admin access by IP: If your administrators work from a fixed IP range, you can configure the server or use a plugin to allow only those IPs to access /wp-admin. This is an effective measure even if an authentication flaw exists.
Hide the default login page: Change the /wp-login.php path to a different URL using a plugin such as WPS Hide Login to reduce automated attacks targeting the default login page.
Set up long-term monitoringLink to heading
Do not wait until after an incident occurs, build a proactive monitoring system to protect your website more effectively.
Follow security alerts: Subscribe to trusted sources such as Wordfence Intelligence, the WPScan Vulnerability Database, or Patchstack. When a plugin you use has a new vulnerability, you will be notified before attackers have a chance to exploit it.
Enable selective auto-updates: WordPress allows you to enable automatic updates for individual plugins. For plugins related to authentication, security, or payments, auto-updates should be enabled so that critical patches are not missed.
Back up regularly and test recovery: A full backup that has already been tested for restoration is the final safety net if all other defenses fail. Make sure backups are stored somewhere completely separate from the main server, not just in the same hosting account.
ConclusionLink to heading
The authentication bypass vulnerability in Tutor LMS Pro (CVE-2026-0953) is a clear reminder that even a small mistake in OAuth handling can lead to serious consequences. If your website uses Tutor LMS Pro, updating to version 3.9.6 or later is mandatory and should not be delayed. At the same time, you should review your entire system to make sure it has not already been exploited.
Remember that proactive protection is always more effective than dealing with the aftermath. Therefore, alongside timely plugin updates, administrators should build a comprehensive security strategy, from access control and login monitoring to independent defense layers, in order to reduce risk when new vulnerabilities emerge.