CVE-2026-39605

Super Custom Login <= 1.1 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Super Custom Login plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1. 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<=1.1
PublishedFebruary 3, 2026
Last updatedApril 15, 2026
Affected pluginsuper-custom-login
Research Plan
Unverified

This research plan targets CVE-2026-39605, a Missing Authorization vulnerability in the **Super Custom Login** plugin (<= 1.1). The vulnerability allows unauthenticated attackers to perform unauthorized actions, typically modifying plugin settings due to the lack of capability checks in administrati…

Show full research plan

This research plan targets CVE-2026-39605, a Missing Authorization vulnerability in the Super Custom Login plugin (<= 1.1). The vulnerability allows unauthenticated attackers to perform unauthorized actions, typically modifying plugin settings due to the lack of capability checks in administrative hooks.


1. Vulnerability Summary

The Super Custom Login plugin fails to implement proper authorization checks (e.g., current_user_can()) on a function responsible for saving plugin configurations. This function is likely hooked to admin_init or registered as an AJAX action via wp_ajax_nopriv_*. Because admin_init is triggered even when accessing admin-ajax.php or admin-post.php (even by unauthenticated users), any logic inside an admin_init hook that lacks a capability check is accessible to any visitor.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php or /wp-admin/admin-post.php (alternatively, any admin-context URL if the hook is admin_init).
  • Action: scl_save_settings or super_custom_login_save (inferred - needs verification in source).
  • Payload Parameter: Likely a POST request containing settings such as scl_logo_url, scl_login_bg_color, or scl_custom_css.
  • Authentication: None (Unauthenticated).
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to /wp-admin/admin-ajax.php.
  2. Hook Execution: WordPress initializes the admin environment, firing the admin_init hook.
  3. Vulnerable Function: The plugin has registered a function (e.g., scl_save_options_callback) to the admin_init hook.
  4. Authorization Failure: The function checks if specific POST parameters are set (e.g., if ( isset( $_POST['scl_submit'] ) )) but fails to verify current_user_can( 'manage_options' ).
  5. Sink: The function calls update_option( 'scl_settings', ... ) with user-supplied data from $_POST.

4. Nonce Acquisition Strategy

If the plugin uses check_admin_referer() or wp_verify_nonce(), we must find where the nonce is leaked.

  1. Identify Shortcodes: Search for add_shortcode in the plugin files to see if any frontend elements exist.
  2. Search for Localized Scripts: Look for wp_localize_script in the codebase.
    • Search command: grep -r "wp_localize_script" .
  3. Execution:
    • If a nonce is leaked in a JS variable (e.g., scl_vars.nonce):
      1. Navigate to the site homepage or login page using browser_navigate.
      2. Execute browser_eval("window.scl_vars?.nonce") to retrieve it.
  4. Bypass Check: Check if the code uses check_admin_referer( '...', '...', false ). If the third parameter is false and the return value isn't checked, the nonce is bypassed.

5. Exploitation Strategy

We will attempt to modify the plugin's settings to change the login page's appearance or inject custom CSS, confirming unauthorized write access.

  • Step 1: Identify the Action and Parameters

    • Search the plugin for update_option.
    • Search command: grep -r "update_option" .
    • Identify the POST key that triggers the update (e.g., scl_update or submit).
  • Step 2: Construct the Payload

    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php (or admin-post.php)
    • Body (URL-encoded):
      action=[INFERRED_ACTION]&scl_logo_url=http://attacker.com/malicious.png&scl_custom_css=body{display:none !important;}&[TRIGGER_PARAM]=1
      
    • Headers: Content-Type: application/x-www-form-urlencoded
  • Step 3: Execute Request

    • Use the http_request tool to send the payload.

6. Test Data Setup

  1. Install and activate the super-custom-login plugin.
  2. (Optional) If the plugin requires a specific page to be visited for nonce leakage, create it:
    • wp post create --post_type=page --post_status=publish --post_content='[super_custom_login_placeholder]'

7. Expected Results

  • The HTTP response should ideally be a 302 redirect or a 200 OK (if AJAX).
  • The option in the WordPress database associated with the plugin settings will be updated with the attacker's values.

8. Verification Steps

After the exploit, verify the changes using WP-CLI:

  1. Check Option Value:
    • wp option get scl_settings (Verify scl_logo_url or scl_custom_css matches the payload).
  2. Visual Confirmation:
    • Navigate to the WordPress login page (/wp-login.php) and check if the custom CSS or logo has been applied.

9. Alternative Approaches

  • If admin_init is not the hook: Check for wp_ajax_nopriv_ handlers. If the plugin uses an AJAX handler for settings but registered it with nopriv, any user can call it.
  • XSS Injection: If the plugin allows saving "Custom JavaScript" or "Footer Text" without sanitization/authorization, escalate the "Missing Authorization" to Stored XSS by injecting <script>alert(document.domain)</script>.
  • Settings Reset: Check if there is a "Reset Settings" action that also lacks authorization, which could be used for an Unauthorized Deletion/Denial of Service attack on the plugin's configuration.

Check if your site is affected.

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