CVE-2026-48970

Really Simple Security – Simple and Performant Security (formerly Really Simple SSL) <= 9.5.10 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
9.5.10.1
Patched in
9d
Time to patch

Description

The Really Simple Security – Simple and Performant Security (formerly Really Simple SSL) plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 9.5.10. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=9.5.10
PublishedJune 3, 2026
Last updatedJune 11, 2026
Affected pluginreally-simple-ssl

What Changed in the Fix

Changes introduced in v9.5.10.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-48970 ## 1. Vulnerability Summary **CVE-2026-48970** is a Missing Authorization vulnerability in the **Really Simple Security** plugin (formerly Really Simple SSL) for WordPress. The flaw exists in the REST API endpoints associated with the Two-Factor Authent…

Show full research plan

Exploitation Research Plan - CVE-2026-48970

1. Vulnerability Summary

CVE-2026-48970 is a Missing Authorization vulnerability in the Really Simple Security plugin (formerly Really Simple SSL) for WordPress. The flaw exists in the REST API endpoints associated with the Two-Factor Authentication (2FA) onboarding feature.

Specifically, the plugin registers a REST route (likely two_fa/skip_onboarding) that fails to implement a permission_callback check or internal user validation. This allows an unauthenticated attacker to programmatically mark any user account—including administrators—as having skipped the 2FA setup process. While this does not provide immediate authentication bypass, it degrades the security posture of the site by allowing an attacker to neutralize 2FA requirements for targeted accounts.

2. Attack Vector Analysis

  • Endpoint: /wp-json/really-simple-security/v1/two_fa/skip_onboarding (Inferred from JS onboarding.js and env.php)
  • HTTP Method: POST
  • Authentication: Unauthenticated (No cookies or credentials required).
  • Payload Format: JSON (processed by RequestStorage.php).
  • Target Parameter: user_id (The ID of the user whose 2FA onboarding is to be skipped).
  • Preconditions: The 2FA feature must be enabled in the plugin settings.

3. Code Flow

  1. Entry Point: An unauthenticated request is sent to the WordPress REST API.
  2. Request Handling: The plugin's RequestStorage class (core/app/Support/Helpers/Storages/RequestStorage.php) intercept the request. The getRequestBody() function reads php://input and performs json_decode on the payload.
  3. Route Matching: The REST API dispatcher matches the request to the really-simple-security/v1 namespace (defined in core/config/env.php).
  4. Vulnerable Logic: The handler function for skip_onboarding (located in the Two-Factor feature controller) receives the user_id from the decoded JSON body.
  5. Missing Check: The handler lacks a call to current_user_can() and does not verify if the request is authenticated. It proceeds to update the user meta (e.g., rsssl_two_fa_status set to skipped) for the provided user_id.

4. Nonce Acquisition Strategy

Based on the source file assets/features/two-fa/assets.min.js, the plugin uses a performFetchOp helper:

u(this,"performFetchOp",(function(e,t){
    var i=n.root+e,
    o={method:r,headers:{"Content-Type":"application/json"}};
    if("POST"===r){o.body=JSON.stringify(t)}
    return fetch(i,o)
}))

Observation: The headers object only specifies Content-Type: application/json. It does not include the X-WP-Nonce header. This confirms that the specific REST endpoints used for onboarding and 2FA initialization are designed to be accessible without a WordPress nonce, making the vulnerability directly exploitable without the need for nonce extraction.

5. Exploitation Strategy

The goal is to unauthenticatedly mark the administrator (User ID 1) as having "skipped" 2FA onboarding.

Step 1: Discover Target User ID

Typically, the primary administrator is User ID 1. This can be verified via the REST API /wp-json/wp/v2/users.

Step 2: Perform Unauthorized Action

Send a POST request to the vulnerable 2FA endpoint.

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/wp-json/really-simple-security/v1/two_fa/skip_onboarding
  • Headers:
    • Content-Type: application/json
  • Body:
    {
      "user_id": 1
    }
    

Step 3: Observe Response

A successful exploit should return a 200 OK response with a JSON body indicating success (e.g., {"success": true}).

6. Test Data Setup

  1. Install Plugin: Install and activate "Really Simple Security" version 9.5.10.
  2. Enable 2FA:
    • Navigate to the plugin settings.
    • Enable the "Two-Factor Authentication" feature.
    • Set the 2FA policy to "Mandatory" for all administrators.
  3. Identify Admin: Ensure there is an administrator user with ID 1.

7. Expected Results

  • Response: The server returns HTTP 200.
  • Side Effect: The target user's 2FA status is modified in the database, allowing them to log in without being prompted to set up 2FA, effectively bypassing the mandatory security policy.

8. Verification Steps

After sending the HTTP request, use wp_cli to inspect the user's metadata:

# Check the 2FA status meta key (inferred name)
wp user meta get 1 rsssl_two_fa_status

Success Condition: The value should return skipped or a similar flag indicating the onboarding was bypassed.

9. Alternative Approaches

If skip_onboarding does not exist or requires different parameters, analyze the JS onboarding.js for other actions handled by performFetchOp. Potential targets include:

  • two_fa/get_backup_codes: If this lacks auth, it leads to a High-severity information disclosure.
  • two_fa/resend_code: Could be used for SMS/Email flooding (Denial of Service/Rate limiting bypass).
  • two_fa/authenticate: If the user_id is trusted from the payload without session verification, this leads to a full Authentication Bypass. (Note: CVE-2024-10924 used a similar vector in earlier versions).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Really Simple Security plugin for WordPress contains a missing authorization vulnerability in its REST API handling 2FA onboarding. Unauthenticated attackers can exploit this to disable or skip mandatory Two-Factor Authentication (2FA) for any user account, including administrators, by sending a crafted JSON request to the skip onboarding endpoint.

Vulnerable Code

// core/app/Support/Helpers/Storages/RequestStorage.php (lines 24-37)
// This class parses the JSON body of requests without verifying nonces or authentication.
private function getRequestBody(): array
{
    $body = [];
    if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
        $input = file_get_contents('php://input');
        $decoded = json_decode($input, true);
        if (is_array($decoded)) {
            $body = $decoded;
        }
    }
    return $body;
}

---

// assets/features/two-fa/assets.min.js
// The JavaScript implementation of the onboarding fetch operation fails to include security headers like X-WP-Nonce.
u(this,"performFetchOp",(function(e,t){
    var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"POST",
    i=n.root+e,
    o={method:r,headers:{"Content-Type":"application/json"}};
    return"POST"===r&&(o.body=JSON.stringify(t)),fetch(i,o)
}))

Security Fix

--- a/core/app/Features/TwoFactor/TwoFactorFeature.php
+++ b/core/app/Features/TwoFactor/TwoFactorFeature.php
@@ -120,6 +120,7 @@
             'methods'  => 'POST',
             'callback' => [ $this, 'skip_onboarding' ],
+            'permission_callback' => function () {
+                return is_user_logged_in();
+            },
         ] );

Exploit Outline

1. Target Discovery: Identify a WordPress site running Really Simple Security (formerly Really Simple SSL) version <= 9.5.10 with 2FA enabled. 2. Target User ID: Determine the User ID of the target account (typically User ID 1 for the primary administrator). 3. Payload Preparation: Construct a JSON payload containing the user_id (e.g., `{"user_id": 1}`). 4. Endpoint Exploitation: Send an unauthenticated POST request to `/wp-json/really-simple-security/v1/two_fa/skip_onboarding` with the JSON payload. 5. Verification: Because the endpoint lacks a `permission_callback` and does not check for a WordPress nonce or authentication cookies, the plugin will process the request and update the user's status to 'skipped' for 2FA onboarding. 6. Outcome: The target administrator can now log in without being forced to set up 2FA, even if the site policy mandates it, effectively weakening the account's security profile.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.