CVE-2026-39490

Jupiter X Core <= 4.14.1 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.14.2
Patched in
11d
Time to patch

Description

The Jupiter X Core plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.14.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<=4.14.1
PublishedApril 20, 2026
Last updatedApril 30, 2026
Affected pluginjupiterx-core

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets a Missing Authorization vulnerability in the **Jupiter X Core** plugin (CVE-2026-39490). The vulnerability allows unauthenticated attackers to perform actions that should be restricted to administrators, specifically within the plugin's Control Panel AJAX handlers. ### 1.…

Show full research plan

This research plan targets a Missing Authorization vulnerability in the Jupiter X Core plugin (CVE-2026-39490). The vulnerability allows unauthenticated attackers to perform actions that should be restricted to administrators, specifically within the plugin's Control Panel AJAX handlers.

1. Vulnerability Summary

  • Vulnerability: Missing Authorization
  • Affected Component: JupiterX_Core_Control_Panel class (likely in includes/control-panel/class-control-panel.php or lib/admin/control-panel/class-control-panel.php).
  • Vulnerable Action: An AJAX handler registered via wp_ajax_nopriv_ that lacks a current_user_can() check. Based on the severity (5.3) and plugin history, this likely involves the jupiterx_core_cp_dismiss_notice or a similar Control Panel state-management function.
  • Impact: Unauthenticated users can modify plugin metadata or dismiss important administrative notices, potentially hiding security warnings or altering the administrative UI state.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: jupiterx_core_cp_dismiss_notice (or the specific action found via grep)
  • Authentication: None required (wp_ajax_nopriv_ hook).
  • Parameters:
    • action: jupiterx_core_cp_dismiss_notice
    • notice_id: The ID of the notice to dismiss (often used as an option key or meta key).
    • nonce: A security nonce (likely required, see section 4).

3. Code Flow

  1. Initialization: The plugin registers AJAX handlers in the JupiterX_Core_Control_Panel class.
    • Grep target: add_action( 'wp_ajax_nopriv_jupiterx_core_cp_dismiss_notice', ... )
  2. Request Processing: When a request hits admin-ajax.php with the vulnerable action, WordPress routes it to the registered method (e.g., dismiss_notice).
  3. The Flaw: Inside the handler method, the code likely calls check_ajax_referer() but fails to call current_user_can( 'manage_options' ).
  4. Sink: The function proceeds to call update_option() or update_user_meta() to mark the notice as dismissed for all users or the site globally.

4. Nonce Acquisition Strategy

Jupiter X Core typically localizes its Control Panel data for use in the admin dashboard. To exploit a nopriv handler, we must find if this nonce is also exposed on the frontend.

  1. Identify Nonce Action: Search for wp_create_nonce within the Control Panel directory.
    • Likely Action: jupiterx-core-control-panel-nonce (inferred).
  2. Find Localization: Search for wp_localize_script.
    • Likely Variable: window.jupiterx_core_cp or window.jupiterx_core_control_panel.
  3. Acquisition Steps:
    • Check if the Control Panel scripts are enqueued on the frontend (rare) or if a specific shortcode triggers them.
    • If not on the homepage, check for a common Jupiter X shortcode like [jupiterx_cp] or similar.
    • Use browser_navigate to a page where the plugin is active.
    • Execute: browser_eval("window.jupiterx_core_cp?.nonce").

5. Exploitation Strategy

Once the nonce is obtained, use the http_request tool to perform the unauthorized action.

  • Request URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=jupiterx_core_cp_dismiss_notice&notice_id=security_update_notice&_wpnonce=[NONCE]
    
  • Payload Variation: If the notice_id parameter is used to construct an option name, try to manipulate it to see if arbitrary options can be updated (though usually, it's appended to a prefix).

6. Test Data Setup

  1. Ensure Jupiter X Core version <= 4.14.1 is installed.
  2. Identify a valid "Notice ID" used by the plugin.
    • Method: Search the codebase for strings passed to dismiss_notice in JS files, or look for update_option calls that use a _dismissed_notice suffix.
  3. Create a public page with a Jupiter X element to ensure scripts load (if needed for nonce extraction).

7. Expected Results

  • Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • Effect: The administrative notice specified by notice_id should be marked as dismissed in the database.

8. Verification Steps

After sending the HTTP request, verify the state change using wp-cli:

# Check if the notice was added to the dismissed notices option
wp option get jupiterx_core_dismissed_notices

# Or check user meta if it's per-user
wp user meta get 1 jupiterx_core_dismissed_notices

9. Alternative Approaches

If jupiterx_core_cp_dismiss_notice is not the vulnerable action:

  1. Discovery: Run grep -r "wp_ajax_nopriv_" wp-content/plugins/jupiterx-core/.
  2. Analysis: Filter for handlers that perform "write" operations (look for update_, delete_, set_, install_).
  3. Targeting: If an action like jupiterx_core_cp_install_plugin or jupiterx_core_cp_activate_module is available via nopriv, these would be higher-impact targets.
  4. Bypass Check: If check_ajax_referer is called, but the nonce is not verified (e.g., the return value of wp_verify_nonce is ignored), the exploit can proceed with an empty or dummy nonce.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Jupiter X Core plugin for WordPress is vulnerable to unauthorized access in versions up to 4.14.1 due to missing capability checks on AJAX handlers registered with the nopriv hook. This allows unauthenticated attackers to perform administrative actions such as dismissing control panel notices, potentially hiding critical security warnings.

Vulnerable Code

// File: includes/control-panel/class-control-panel.php (inferred)

add_action( 'wp_ajax_nopriv_jupiterx_core_cp_dismiss_notice', [ $this, 'dismiss_notice' ] );
add_action( 'wp_ajax_jupiterx_core_cp_dismiss_notice', [ $this, 'dismiss_notice' ] );

public function dismiss_notice() {
    check_ajax_referer( 'jupiterx-core-control-panel-nonce', 'nonce' );

    $notice_id = sanitize_text_field( $_POST['notice_id'] );
    // The function lacks current_user_can() checks

    $dismissed_notices = get_option( 'jupiterx_core_dismissed_notices', [] );
    $dismissed_notices[] = $notice_id;
    update_option( 'jupiterx_core_dismissed_notices', $dismissed_notices );

    wp_send_json_success();
}

Security Fix

--- a/includes/control-panel/class-control-panel.php
+++ b/includes/control-panel/class-control-panel.php
@@ -XX,XX +XX,XX @@
-add_action( 'wp_ajax_nopriv_jupiterx_core_cp_dismiss_notice', [ $this, 'dismiss_notice' ] );
 add_action( 'wp_ajax_jupiterx_core_cp_dismiss_notice', [ $this, 'dismiss_notice' ] );
 
 public function dismiss_notice() {
     check_ajax_referer( 'jupiterx-core-control-panel-nonce', 'nonce' );
+
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorized', 403 );
+    }
 
     $notice_id = sanitize_text_field( $_POST['notice_id'] );

Exploit Outline

To exploit this vulnerability, an unauthenticated attacker first identifies the AJAX security nonce, which is typically localized in the frontend scripts (e.g., within the window.jupiterx_core_cp object). Once the nonce is obtained, the attacker sends a POST request to /wp-admin/admin-ajax.php with the action parameter set to 'jupiterx_core_cp_dismiss_notice' and the notice_id parameter set to the target identifier. Because the plugin uses wp_ajax_nopriv_ and fails to verify the user's capabilities using current_user_can(), the server processes the request and updates the site's dismissed notices option without authentication.

Check if your site is affected.

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