CVE-2026-4121

Kcaptcha <= 1.0.1 - Cross-Site Request Forgery to Settings Update

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Kcaptcha plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to and including 1.0.1. This is due to missing nonce validation in the plugin's settings page handler (admin/setting.php). The settings form does not include a wp_nonce_field() and the form processing code does not call wp_verify_nonce() or check_admin_referer() before saving settings to the database via $wpdb->update(). This makes it possible for unauthenticated attackers to modify the plugin's CAPTCHA settings (enabling or disabling CAPTCHA on login, registration, lost password, and comment forms) via a forged request, granted they can trick a site administrator into performing an action such as clicking 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<=1.0.1
PublishedApril 21, 2026
Last updatedApril 22, 2026
Affected pluginkcaptcha
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-4121 (Kcaptcha CSRF) ## 1. Vulnerability Summary The **Kcaptcha** plugin for WordPress (versions up to and including 1.0.1) is vulnerable to **Cross-Site Request Forgery (CSRF)**. The vulnerability exists in the plugin's settings management logic located in `a…

Show full research plan

Exploitation Research Plan: CVE-2026-4121 (Kcaptcha CSRF)

1. Vulnerability Summary

The Kcaptcha plugin for WordPress (versions up to and including 1.0.1) is vulnerable to Cross-Site Request Forgery (CSRF). The vulnerability exists in the plugin's settings management logic located in admin/setting.php. The plugin fails to include a security nonce in the settings form and neglects to verify a nonce when processing the form submission. This allows an attacker to trick a logged-in administrator into involuntarily modifying the plugin's CAPTCHA configurations, potentially disabling security measures on critical forms (login, registration, etc.).

2. Attack Vector Analysis

  • Vulnerable Endpoint: wp-admin/admin.php?page=kcaptcha (inferred slug).
  • HTTP Method: POST.
  • Vulnerable File: admin/setting.php.
  • Vulnerable Logic: The code lacks wp_nonce_field() in the HTML form and lacks check_admin_referer() or wp_verify_nonce() in the PHP processing block.
  • Authentication Requirement: Administrator (victim must be logged in).
  • Preconditions: An administrator must be induced to click a link or visit a page controlled by the attacker while their WordPress session is active.

3. Code Flow

  1. Registration: The plugin registers an admin menu page, likely using add_menu_page() or add_options_page(), pointing to admin/setting.php as the callback or included file.
  2. Form Rendering: When the admin visits the settings page, admin/setting.php renders an HTML <form>. This form lacks the <?php wp_nonce_field(...); ?> call.
  3. Form Submission: Upon clicking "Save" or "Submit", the browser sends a POST request to the same URL or admin-post.php.
  4. Processing: The top of admin/setting.php (or an admin_init hook) checks if $_POST variables are present.
  5. Database Sink: Without any nonce check, the code proceeds to update settings in the database, specifically using $wpdb->update() on the plugin's configuration table (likely wp_kcaptcha or updating the wp_options table).

4. Nonce Acquisition Strategy

No nonce is required.
According to the vulnerability description, the plugin completely lacks nonce validation in the settings handler. An unauthenticated attacker does not need to bypass a nonce check; they only need to forge the request that an administrator would normally send.

5. Exploitation Strategy

The goal is to demonstrate that a POST request sent to the settings page can modify plugin options without a nonce.

Step-by-Step Plan:

  1. Preparation: Identify the exact POST parameters used by the plugin to toggle CAPTCHA. Based on the description, these likely correspond to:
    • kcaptcha_login (inferred)
    • kcaptcha_registration (inferred)
    • kcaptcha_lostpassword (inferred)
    • kcaptcha_comment (inferred)
    • submit (inferred - often used as a trigger)
  2. Execution: Use the http_request tool to send a POST request to wp-admin/admin.php?page=kcaptcha with the admin's session cookies.
  3. Payload:
    • URL: http://localhost:8080/wp-admin/admin.php?page=kcaptcha
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: kcaptcha_login=0&kcaptcha_registration=0&kcaptcha_lostpassword=0&kcaptcha_comment=0&submit=Save+Settings

6. Test Data Setup

  1. Plugin Installation: Install and activate the kcaptcha plugin (version <= 1.0.1).
  2. Initial Configuration: Manually enable all CAPTCHA options in the admin UI to ensure we have a state to "unset" via CSRF.
  3. Admin Victim: Ensure an administrator user exists (default: admin / password).
  4. Session Acquisition: The agent must obtain the admin cookies to simulate the CSRF attack.

7. Expected Results

  • The server should return a 200 OK or a 302 Redirect back to the settings page.
  • No "Are you sure you want to do this?" (WordPress's default nonce-failure message) should appear.
  • The database values for the CAPTCHA settings should be updated to the attacker-supplied values (e.g., all disabled).

8. Verification Steps

After the http_request, use WP-CLI to verify the change in state:

  1. Check Options Table:
    wp option get kcaptcha_settings (inferred name)
    OR
  2. Check Plugin Table:
    wp db query "SELECT * FROM wp_kcaptcha" (inferred table name)
  3. Check Front-end:
    Navigate to the login page (/wp-login.php) and verify that the CAPTCHA field is no longer visible.

9. Alternative Approaches

If the settings are not stored in wp_options or a custom table, they might be stored as individual options.

  • Individual Option Check: wp option get kcaptcha_login
  • Form Discovery: If the inferred parameters are incorrect, the agent should first perform a GET request to wp-admin/admin.php?page=kcaptcha and use browser_eval to extract all input names from the form:
    browser_eval("Array.from(document.querySelectorAll('input[name]')).map(i => i.name)")

This discovery step ensures the POST payload matches the exact version of the plugin being tested.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Kcaptcha plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 1.0.1. This vulnerability exists because the plugin's settings page handler in 'admin/setting.php' does not implement nonce validation, allowing attackers to modify CAPTCHA configurations by tricking an administrator into submitting a forged request.

Vulnerable Code

// admin/setting.php (approximate based on description)

if (isset($_POST['submit'])) {
    // Vulnerable: No check_admin_referer() or wp_verify_nonce() call here
    $wpdb->update($wpdb->prefix . 'kcaptcha', array(
        'login' => $_POST['kcaptcha_login'],
        'registration' => $_POST['kcaptcha_registration'],
        'lostpassword' => $_POST['kcaptcha_lostpassword'],
        'comment' => $_POST['kcaptcha_comment']
    ), array('id' => 1));
}

// ---

// admin/setting.php (form rendering)

<form method="post" action="">
    <!-- Vulnerable: Missing wp_nonce_field() -->
    <input type="checkbox" name="kcaptcha_login" value="1">
    <input type="submit" name="submit" value="Save">
</form>

Security Fix

--- admin/setting.php
+++ admin/setting.php
@@ -1,4 +1,5 @@
 if (isset($_POST['submit'])) {
+    check_admin_referer('kcaptcha_update_settings');
     $wpdb->update($wpdb->prefix . 'kcaptcha', array(
         'login' => $_POST['kcaptcha_login'],
         'registration' => $_POST['kcaptcha_registration'],
@@ -10,4 +11,5 @@
 ...
 <form method="post" action="">
+    <?php wp_nonce_field('kcaptcha_update_settings'); ?>
     <input type="checkbox" name="kcaptcha_login" value="1">
     <input type="submit" name="submit" value="Save">

Exploit Outline

The exploit targets the plugin's settings management endpoint. An unauthenticated attacker crafts a malicious HTML page containing a hidden form that targets 'wp-admin/admin.php?page=kcaptcha' via the POST method. The form contains parameters such as 'kcaptcha_login=0', 'kcaptcha_registration=0', and 'submit=Save', which are intended to disable the CAPTCHA functionality. When a logged-in administrator visits the attacker's page, the form is automatically submitted using the administrator's session cookies. Since the plugin lacks nonce verification, it processes the request and updates the database settings, effectively disabling CAPTCHA protections across the site.

Check if your site is affected.

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