Understanding and Fixing Authentication Bypass Vulnerabilities: A Case Study on Really Simple SSL

Introduction

In the world of WordPress plugins, security vulnerabilities can have far-reaching consequences, especially when they affect widely used tools like Really Simple SSL. A recent vulnerability in versions 9.0.0 to 9.1.1.1 exposed websites to the risk of authentication bypass. However, the vulnerability only affected sites where the Two-Factor Authentication (2FA) feature was enabled.

This blog post explores how the vulnerability occurred, the steps taken to fix it in version 9.1.2, and key takeaways for developers to prevent similar issues in the future.

Understanding the Vulnerability

The vulnerability existed in the plugin’s Two-Factor Authentication (2FA) feature, which is disabled by default. Specifically, it affected the API endpoint reallysimplyssl/v1/two-fa/skip_onboarding, which was designed to allow users to bypass the 2FA onboarding process.

Interestingly, it was possible for an unauthenticated user to probe whether the site has the 2FA feature enabled by querying the WordPress REST API for the reallysimplyssl/v1/two-fa endpoint (note the namespaces below).

Root Cause

  1. Improper Error Handling:
    • The function check_login_and_get_user validated the login_nonce parameter and attempted to retrieve a user object.
    • However, the calling function, skip_onboarding, ignored the result of this validation. Even if check_login_and_get_user returned an error, the process continued to authenticate the user and set an authentication cookie.
  2. Unrestricted Access:
    • The endpoint was configured with a permission_callback set to __return_true, meaning any unauthenticated user could interact with it.

Exploitation

An attacker could exploit this vulnerability as follows:

  1. Send a POST request to the skip_onboarding endpoint with:
    • A valid user_id (e.g., 1 for administrators).
    • An invalid or empty login_nonce.
  2. The plugin would authenticate the user regardless of nonce validity, allowing the attacker to log in as the specified user and gain full access to the site.

It’s been given a 9.8 CVSS score as it’s really trivial to exploit. Some proof-of-concept code was developed to test and evaluate the issue further. It was possible re-create the issue and generate an admin cookie on demand. This cookie can then be used to access ‘/wp-admin’ as an administrator user.

The Fix

In version 9.1.2, the developers implemented two key changes to eliminate the vulnerability.

Immediate Termination on Validation Failure

The check_login_and_get_user function was updated to terminate execution immediately if nonce validation failed:

if ( ! Rsssl_Two_Fa_Authentication::verify_login_nonce( $user_id, $login_nonce ) ) {
    wp_die();
}

Stricter User Validation

The function also throws an exception if the user_id does not correspond to a valid user:

$user = get_user_by('id', $user_id);
if (!$user) {
    throw new Exception('User not found');
}

Outcome

These changes ensure that invalid requests are terminated early, preventing unauthorized access. The calling function no longer proceeds to authenticate or redirect the user if the validation fails.

Key Takeaways

1. Validate Inputs at Every Layer

Never assume that validation has already been performed. Validate inputs at each layer of your application, especially for public-facing endpoints.

For example:

  • Check that required parameters (like user_id and login_nonce) are present and valid.
  • Ensure retrieved data (e.g., get_user_by) is valid before proceeding.

2. Never Ignore Validation Results

If a function performs critical validation, its return value must always be checked. For example:

$user = $this->check_login_and_get_user( $user_id, $login_nonce );

if ( is_a( $user, 'WP_REST_Response' ) ) {
    return $user; // Stop execution if validation fails
}

3. Use Secure permission_callback Logic

While some endpoints, such as those for authentication, need to allow unauthenticated access, avoid setting permission_callback to __return_true without additional safeguards.

Consider adding checks for specific parameters or conditions:

'permission_callback' => function( $request ) {
    $user_id = $request->get_param('user_id');
    return is_numeric($user_id) && ! empty($user_id);
},

4. Handle Errors Gracefully

Avoid generic termination methods like wp_die() in REST API contexts. Instead, return structured error responses to help users debug issues securely. It’s likely that the current fix was to stop the vulnerability from being exploited, and that the code will be revised in subsequent versions.

5. Explore Endpoint Discovery Prevention

Developers may also consider measures to prevent unauthenticated users from discovering sensitive endpoints, such as limiting unauthenticated access or introducing additional authentication layers. While this wasn’t implemented in this fix, it’s a concept worth exploring for added security.

Conclusion

The authentication bypass vulnerability in Really Simple SSL underscores the importance of rigorous validation, secure API design, careful handling of public-facing endpoints, and ongoing training and awareness for developers.

Version 9.1.2 of the plugin successfully addresses this issue with stricter validation and improved error handling. It’s unknown how many users are using the 2FA feature, but the lessons here are relevant for any developer working with authentication or REST API functionality within WordPress.

This case highlights a broader truth: security testing must be an integral part of the development process. By thoroughly testing code for potential vulnerabilities, developers can proactively address risks before they become issues.

At BlogSecurity, we’re working on tools to make security testing easier and more accessible for developers. Sign up for our beta program to be the first to try it when it launches.

References

WordPress.org. (n.d.) Really Simple SSL. Available at: https://wordpress.org/plugins/really-simple-ssl/ (Accessed: 15 November 2024).

Montti, R. (2024, November 15). WordPress Security Plugin Vulnerability Endangers 4 Million+ Sites. Search Engine Journal. Retrieved from https://www.searchenginejournal.com/wordpress-security-plugin-vulnerability-endangers-4-million-sites/532701/

Wordfence. (2024, November 14). 4,000,000 WordPress Sites Using Really Simple Security Free and Pro Versions Affected by Critical Authentication Bypass Vulnerability. Retrieved from https://www.wordfence.com/blog/2024/11/really-simple-security-vulnerability/

Read more: Understanding and Fixing Authentication Bypass Vulnerabilities: A Case Study on Really Simple SSL

Story added 16. November 2024, content source with full text you can find at link above.