Really Simple Security – Simple and Performant Security (formerly Really Simple SSL) <= 9.5.10 - Missing Authorization
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:NTechnical Details
<=9.5.10What Changed in the Fix
Changes introduced in v9.5.10.1
Source Code
WordPress.org SVN# 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 JSonboarding.jsandenv.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
- Entry Point: An unauthenticated request is sent to the WordPress REST API.
- Request Handling: The plugin's
RequestStorageclass (core/app/Support/Helpers/Storages/RequestStorage.php) intercept the request. ThegetRequestBody()function readsphp://inputand performsjson_decodeon the payload. - Route Matching: The REST API dispatcher matches the request to the
really-simple-security/v1namespace (defined incore/config/env.php). - Vulnerable Logic: The handler function for
skip_onboarding(located in the Two-Factor feature controller) receives theuser_idfrom the decoded JSON body. - 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_statusset toskipped) for the provideduser_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
- Install Plugin: Install and activate "Really Simple Security" version 9.5.10.
- Enable 2FA:
- Navigate to the plugin settings.
- Enable the "Two-Factor Authentication" feature.
- Set the 2FA policy to "Mandatory" for all administrators.
- 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 theuser_idis 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).
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
@@ -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.