CVE-2026-6701

addfreespace <= 0.1.3 - Cross-Site Request Forgery to Stored Cross-Site Scripting via Settings Page

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 addfreespace plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 0.1.3. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to update settings and inject malicious web scripts 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<=0.1.3
PublishedMay 4, 2026
Last updatedMay 5, 2026
Affected pluginaddfreespace
Research Plan
Unverified

# Research Plan: CVE-2026-6701 - CSRF to Stored XSS in addfreespace ## 1. Vulnerability Summary The **addfreespace** plugin (<= 0.1.3) contains a Cross-Site Request Forgery (CSRF) vulnerability in its settings management logic. The plugin fails to perform nonce validation when saving its configurat…

Show full research plan

Research Plan: CVE-2026-6701 - CSRF to Stored XSS in addfreespace

1. Vulnerability Summary

The addfreespace plugin (<= 0.1.3) contains a Cross-Site Request Forgery (CSRF) vulnerability in its settings management logic. The plugin fails to perform nonce validation when saving its configuration. This oversight allows an unauthenticated attacker to craft a malicious request that, when executed by a logged-in administrator, updates the plugin's settings. Because the settings fields do not sufficiently sanitize or escape input, this CSRF can be used to inject malicious scripts (Stored XSS) into the database, which are then executed in the context of the administrator's browser or on the site's frontend.

2. Attack Vector Analysis

  • Vulnerable Endpoint: wp-admin/options-general.php?page=addfreespace (inferred slug) or wp-admin/admin-post.php.
  • Attack Type: CSRF leading to Stored XSS.
  • HTTP Method: POST.
  • Payload Carry: Form parameters used for settings (likely names like afs_content, afs_text, or similar).
  • Authentication Level: Unauthenticated (attacker-initiated) via an authenticated Administrator (victim).
  • Preconditions: The attacker must trick a site administrator into clicking a link or visiting a page hosting a malicious auto-submitting form.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers a settings page using add_options_page() or add_menu_page() within an admin_menu hook.
  2. Processing Logic: The settings saving logic is either:
    • Inside the callback function for the menu page (triggered when $_POST is detected).
    • Hooked to admin_init.
    • Hooked to admin_post_ actions.
  3. Vulnerable Path:
    • The code checks for a submit parameter (e.g., isset($_POST['submit'])).
    • CRITICAL FAILURE: It fails to call check_admin_referer() or wp_verify_nonce().
    • The code calls update_option('afs_settings', $_POST['...']) or similar without proper sanitization (e.g., wp_kses).
  4. Sink: The stored option is later echoed back in the admin settings page or on the frontend using get_option() without escaping (e.g., echo $option_value instead of echo esc_html($option_value)).

4. Nonce Acquisition Strategy

According to the vulnerability description, nonce validation is missing or incorrect.

  • If missing: No nonce is required in the exploit request.
  • If incorrect: It usually implies the code calls wp_verify_nonce($nonce, -1) or some other weak action string.

Initial approach: Assume the nonce check is entirely missing and attempt the CSRF without any nonce parameter.

5. Exploitation Strategy

Step 1: Discover Field Names

The agent must first identify the exact POST parameters used to save settings.

  1. Navigate to the settings page: browser_navigate("/wp-admin/options-general.php?page=addfreespace").
  2. If the slug is different, find it with: grep -rn "add_options_page" /var/www/html/wp-content/plugins/addfreespace.
  3. Inspect the HTML form to find the name attributes of the text inputs and the submit button.

Step 2: Construct the CSRF Payload

Once the field names (e.g., afs_custom_text and afs_save) are identified, the payload will be:

  • XSS Payload: <script>alert(document.domain)</script>
  • CSRF Target: The URL identified in the form's action attribute (usually the same settings page URL or admin-post.php).

Step 3: Execute the Exploit (Simulated CSRF)

Since the agent can simulate an admin session, it will use http_request with admin cookies to submit the malicious form data, mimicking what an admin's browser would do when triggered by a CSRF.

Example Request (Inferred):

POST /wp-admin/options-general.php?page=addfreespace HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cookie: [ADMIN_COOKIES]

afs_custom_text=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&afs_save=Save+Changes

6. Test Data Setup

  1. Plugin Installation: Ensure addfreespace version 0.1.3 is installed and active.
  2. Admin User: Use the existing administrator account.
  3. No Nonce Required: The plan assumes no specific setup is needed because the flaw is a lack of protection.

7. Expected Results

  • The http_request should return a 302 redirect or a 200 OK indicating the settings were saved.
  • When the agent (as Admin) navigates back to the settings page, the alert(1) should fire (observable via browser_navigate or checking the source for the raw script tag).

8. Verification Steps

  1. Check Database: Use WP-CLI to verify the malicious payload is stored in the options table.
    wp option get [OPTION_NAME_FOUND_DURING_RESEARCH]
    
  2. Verify Rendering: Navigate to the settings page or the frontend (wherever the option is displayed) and check for the unescaped script:
    # Use browser_navigate and check for the string
    browser_navigate("/wp-admin/options-general.php?page=addfreespace")
    # Verify the payload exists in the page source
    

9. Alternative Approaches

  • Action Hook Search: If the settings page uses options.php, the CSRF might be more difficult because WordPress Core protects options.php with its own nonces. However, if the plugin uses a custom action in admin-post.php or handles the POST directly in the menu callback, it bypasses Core's protection.
  • Frontend XSS: If the injected content is meant to be displayed on the site's frontend (e.g., as a "Free Space" notice), navigate to the homepage to verify the XSS fires for visitors as well.
  • Bypassing Weak Nonce: If a nonce is present but uses a weak action (like -1), the agent can try to grab any valid nonce from the page source (using browser_eval) and see if the plugin accepts it.
Research Findings
Static analysis — not yet PoC-verified

Summary

The addfreespace plugin (<= 0.1.3) is vulnerable to Cross-Site Request Forgery (CSRF) because it fails to perform nonce validation when saving plugin settings. This allows an attacker to trick a logged-in administrator into updating settings with malicious scripts, leading to Stored Cross-Site Scripting (XSS).

Vulnerable Code

// addfreespace.php

function afs_options_page() {
    // ... (logic to display page)
    if (isset($_POST['info_update'])) {
        // Vulnerability: No check_admin_referer() or wp_verify_nonce() call
        // Vulnerability: No sanitization of input before update_option()
        update_option('afs_content', $_POST['afs_content']);
        update_option('afs_before_after', $_POST['afs_before_after']);
        echo '<div class="updated"><p><strong>Settings updated.</strong></p></div>';
    }

    $afs_content = get_option('afs_content');
    // ...
    // Vulnerability: Outputting stored option without escaping
    echo '<textarea name="afs_content">' . $afs_content . '</textarea>';
}

Security Fix

--- addfreespace.php
+++ addfreespace.php
@@ -10,8 +10,10 @@
 function afs_options_page() {
     if (isset($_POST['info_update'])) {
+        check_admin_referer('afs_save_settings');
-        update_option('afs_content', $_POST['afs_content']);
-        update_option('afs_before_after', $_POST['afs_before_after']);
+        update_option('afs_content', wp_kses_post($_POST['afs_content']));
+        update_option('afs_before_after', sanitize_text_field($_POST['afs_before_after']));
         echo '<div class="updated"><p><strong>Settings updated.</strong></p></div>';
     }
 
@@ -20,6 +22,7 @@
     ?>
     <form method="post">
+        <?php wp_nonce_field('afs_save_settings'); ?>
-        <textarea name="afs_content"><?php echo $afs_content; ?></textarea>
+        <textarea name="afs_content"><?php echo esc_textarea($afs_content); ?></textarea>
         <input type="submit" name="info_update" value="Save Changes">
     </form>
     <?php

Exploit Outline

1. Identify the settings page endpoint (e.g., /wp-admin/options-general.php?page=addfreespace) and the POST parameters used for saving (e.g., afs_content, info_update). 2. Create a malicious HTML file or page containing a hidden form that targets the settings endpoint. 3. Include a Stored XSS payload in the form data, such as <script>alert(document.domain)</script>, assigned to the setting parameter (afs_content). 4. Use social engineering or a malicious link to trick an authenticated WordPress administrator into visiting the attacker's page. 5. The form automatically submits using the administrator's cookies, bypassing the lack of CSRF protection to update the plugin's settings in the database. 6. The script will execute whenever the settings page is loaded by an administrator or wherever the affected setting is rendered on the site.

Check if your site is affected.

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