CVE-2026-2023

WP Plugin Info Card <= 6.2.0 - Cross-Site Request Forgery to Arbitrary Custom Plugin Entry Creation

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
6.3.0
Patched in
1d
Time to patch

Description

The WP Plugin Info Card plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 6.2.0. This is due to missing nonce validation in the ajax_save_custom_plugin() function, which is disabled by prefixing the check with 'false &&'. This makes it possible for unauthenticated attackers to create or modify custom plugin entries via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=6.2.0
PublishedFebruary 17, 2026
Last updatedFebruary 18, 2026
Affected pluginwp-plugin-info-card

What Changed in the Fix

Changes introduced in v6.3.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to demonstrate a Cross-Site Request Forgery (CSRF) vulnerability in the **WP Plugin Info Card** plugin, which allows an attacker to create or modify custom plugin entries by tricking an administrator into submitting a forged request. ### 1. Vulnerability Summar…

Show full research plan

This research plan outlines the steps to demonstrate a Cross-Site Request Forgery (CSRF) vulnerability in the WP Plugin Info Card plugin, which allows an attacker to create or modify custom plugin entries by tricking an administrator into submitting a forged request.

1. Vulnerability Summary

  • Vulnerability: Cross-Site Request Forgery (CSRF) to Arbitrary Custom Plugin Entry Creation.
  • Affected Function: MediaRon\WPPIC\Admin\Init::ajax_save_custom_plugin().
  • File: php/Admin/Init.php.
  • Nature of Flaw: The plugin fails to validate WordPress nonces in the ajax_save_custom_plugin() function. According to the vulnerability description, the nonce check was intentionally or accidentally disabled by prefixing the condition with false &&, causing the verification to always be skipped.
  • Impact: An unauthenticated attacker can create new "Custom Plugin" entries (likely stored as a Custom Post Type) or modify existing ones if they can trick a logged-in administrator into clicking a link or visiting a malicious site.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php.
  • Action: wppic_save_custom_plugin.
  • Method: POST.
  • Authentication: Required (Administrator). The attack relies on the administrator's active session.
  • Payload Parameters (Inferred from plugin purpose and JS structure):
    • action: wppic_save_custom_plugin
    • id: (Optional) The ID of the post to modify. Omit or set to 0 for new entries.
    • title: The name of the custom plugin.
    • slug: The slug for the plugin.
    • version: Plugin version string.
    • author: Author name.
    • description: Plugin description.
    • nonce: (Optional/Any value) Due to the false && bypass, the server ignores the validity of this token.

3. Code Flow

  1. Entry Point: The AJAX action is registered in php/Admin/Init.php's constructor:
    add_action( 'wp_ajax_wppic_save_custom_plugin', array( $this, 'ajax_save_custom_plugin' ) );
  2. Execution: When a POST request is sent to admin-ajax.php with action=wppic_save_custom_plugin, WordPress invokes the ajax_save_custom_plugin() method.
  3. Vulnerable Sink: Inside ajax_save_custom_plugin(), the code attempts a nonce check:
    if ( false && ! wp_verify_nonce( ... ) ) { ... }
  4. Bypass: Because false && anything is always false, the error block is never entered.
  5. Persistence: The function proceeds to process the $_POST data and uses wp_insert_post() or update_post_meta() to store the custom plugin entry in the database.

4. Nonce Acquisition Strategy (Optional)

While the vulnerability description states the nonce check is bypassed, a robust exploit should identify where the nonce would have been located if it were enforced.

  1. Shortcode/Page: The Custom Plugin management interface is located in the WordPress Admin dashboard under WP Plugin Info Card > Custom Plugins.
  2. JS Localization: The script dist/wppic-admin-custom-plugin.js is enqueued for this page.
  3. Extraction:
    • Navigate to /wp-admin/admin.php?page=wppic-custom-plugins (inferred slug).
    • Use browser_eval to find localized data. The plugin likely uses a global JS object to store settings.
    • Check window.wppic_admin_custom_plugin or similar.
    • Note: In this specific CVE, the nonce value can be any string (e.g., 1234567890) because the server-side check is disabled.

5. Exploitation Strategy

The goal is to create a new Custom Plugin entry via an auto-submitting HTML form (simulating a CSRF attack).

Step-by-Step:

  1. Identify the base URL of the WordPress instance.
  2. Construct a POST request to admin-ajax.php.
  3. Include parameters that define a new plugin entry.

Example Request (using http_request):

{
  "method": "POST",
  "url": "http://localhost:8888/wp-admin/admin-ajax.php",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": "action=wppic_save_custom_plugin&title=CSRF_Exploit_Plugin&slug=csrf-plugin&version=1.3.37&author=Attacker&description=This+was+created+via+CSRF&nonce=deadbeef"
}

6. Test Data Setup

  1. Plugin Activation: Ensure wp-plugin-info-card version 6.2.0 is installed and active.
  2. Admin Access: Ensure an administrator user exists (to provide the session context for the CSRF).
  3. Identify Post Type: Custom plugins are likely stored as a post type named wppic-custom-plugin (or similar). Run wp post-type list to confirm.

7. Expected Results

  • The server should respond with a JSON success message: {"success":true,"data":{...}}.
  • A new post of the custom plugin type should be created in the wp_posts table.
  • The post meta should contain the slug, version, and author provided in the payload.

8. Verification Steps

After executing the http_request, verify the creation of the plugin entry via WP-CLI:

  1. List Custom Plugins:
    wp post list --post_type=wppic-custom-plugin --format=ids
  2. Check Metadata:
    Replace <ID> with the ID found in the previous step:
    wp post get <ID> --field=post_title
    wp post get <ID> --field=post_content
    wp post-meta list <ID>
  3. Confirm Lack of Nonce Check:
    Retry the exploit with an empty nonce parameter. If it still succeeds, the false && bypass is confirmed.

9. Alternative Approaches

If the simple POST fails:

  • JSON Payload: Check if the AJAX handler expects application/json instead of form-urlencoded. This is common in React-based admin panels (as indicated by the react dependency in wppic-admin-custom-plugin.asset.php).
  • Modification: Attempt to modify an existing entry by providing an id parameter. First, manually create a custom plugin to get its ID, then attempt to change its title via CSRF.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Plugin Info Card plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 6.2.0. This is caused by a disabled nonce check in the `ajax_save_custom_plugin()` function, where the verification logic is prefixed with 'false &&', allowing attackers to create or modify custom plugin entries by tricking an administrator into performing an action.

Vulnerable Code

// php/Admin/Init.php

public function ajax_save_custom_plugin() {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    $nonce = sanitize_text_field( filter_input( INPUT_POST, 'nonce', FILTER_DEFAULT ) );
    if ( false && ! wp_verify_nonce( $nonce, 'wppic-admin-custom-plugin-save' ) ) {
        wp_send_json_error(
            array(
                'message'     => __( 'Nonce verification failed', 'wp-plugin-info-card' ),
                'type'        => 'error',
                'dismissable' => true,
            )
        );
    }

Security Fix

--- php/Admin/Init.php
+++ php/Admin/Init.php
@@ -342,7 +342,7 @@
 		}
 
 		$nonce = sanitize_text_field( filter_input( INPUT_POST, 'nonce', FILTER_DEFAULT ) );
-		if ( false && ! wp_verify_nonce( $nonce, 'wppic-admin-custom-plugin-save' ) ) {
+		if ( ! wp_verify_nonce( $nonce, 'wppic-admin-custom-plugin-save' ) ) {
 			wp_send_json_error(
 				array(
 					'message'     => __( 'Nonce verification failed', 'wp-plugin-info-card' ),

Exploit Outline

The exploit targets the AJAX endpoint `admin-ajax.php` using the `wppic_save_custom_plugin` action. Because the server-side nonce verification is effectively disabled with a `false &&` condition, an attacker only needs to trick a logged-in administrator into visiting a malicious page that auto-submits a POST request. The payload includes parameters like `title`, `slug`, `version`, `author`, and `description` to create a new custom plugin entry or an `id` to modify an existing one. Since the nonce check always evaluates to false, any value (or no value) for the `nonce` parameter is accepted.

Check if your site is affected.

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