CVE-2026-1244

Forms Bridge <= 4.2.5 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'id' Shortcode Attribute

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

Description

The Forms Bridge – Infinite integrations plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'id' shortcode attribute in the 'financoop_campaign' shortcode in all versions up to, and including, 4.2.5. This is due to insufficient input sanitization and output escaping on the user-supplied 'id' parameter in the forms_bridge_financoop_shortcode_error function. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.2.5
PublishedJanuary 27, 2026
Last updatedJanuary 28, 2026
Affected pluginforms-bridge

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1244 (Forms Bridge) ## 1. Vulnerability Summary The **Forms Bridge – Infinite integrations** plugin (<= 4.2.5) contains a stored cross-site scripting (XSS) vulnerability. The flaw exists within the `financoop_campaign` shortcode handler. Specifically, the `id`…

Show full research plan

Exploitation Research Plan: CVE-2026-1244 (Forms Bridge)

1. Vulnerability Summary

The Forms Bridge – Infinite integrations plugin (<= 4.2.5) contains a stored cross-site scripting (XSS) vulnerability. The flaw exists within the financoop_campaign shortcode handler. Specifically, the id attribute provided by the user is passed to the function forms_bridge_financoop_shortcode_error (inferred to be an error-reporting helper), which outputs the raw value of the id attribute without proper sanitization or context-aware escaping (e.g., esc_html or esc_attr). This allows a user with Contributor-level privileges or higher to inject malicious JavaScript into a post, which executes when any user views the rendered page.

2. Attack Vector Analysis

  • Endpoint: wp-admin/post.php (Standard WordPress post creation/edition).
  • Shortcode: [financoop_campaign id="PAYLOAD"]
  • Carrier Attribute: id
  • Required Authentication: Contributor-level (can create/edit posts but cannot publish by default, though previews still trigger the shortcode rendering).
  • Preconditions: The plugin must be active. The exploit is triggered when the shortcode's "error" path is taken (e.g., providing an id that does not correspond to a valid campaign).

3. Code Flow

  1. Registration: The plugin registers the shortcode (likely in includes/class-forms-bridge.php or similar) using add_shortcode('financoop_campaign', 'CALLBACK_FUNCTION').
  2. Execution: When a post containing the shortcode is rendered, the callback function is invoked.
  3. Logic Path: The callback extracts attributes using shortcode_atts(). It likely checks if the provided id is valid or exists in the database/API.
  4. Sink: If the id is invalid, the code calls forms_bridge_financoop_shortcode_error($atts['id']).
  5. Vulnerable Output: The function forms_bridge_financoop_shortcode_error (inferred) performs a direct echo or returns a string containing the raw $id parameter:
    // Inferred Vulnerable Logic
    function forms_bridge_financoop_shortcode_error($id) {
        return "Forms Bridge Error: Campaign with ID $id was not found."; // No escaping!
    }
    

4. Nonce Acquisition Strategy

This vulnerability is exploited through the standard WordPress post-editor workflow.

  1. Creation: A Contributor logs in and visits wp-admin/post-new.php.
  2. Nonces: WordPress automatically generates the _wpnonce and _wp_http_referer required for post saving/autosaving within the editor page.
  3. Extraction:
    • Use browser_navigate to go to /wp-admin/post-new.php.
    • Use browser_eval to extract the _wpnonce from the form field name="_wpnonce".
    • Alternatively, use the http_request tool to perform a POST to wp-admin/post.php using the extracted nonce.

Note: Since this is a Stored XSS via shortcode, the exploit payload is simply the text content of the post.

5. Exploitation Strategy

Step 1: Authenticate as Contributor

  • Perform login and obtain session cookies.

Step 2: Create a Malicious Post

  • Request: POST /wp-admin/post.php
  • Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • post_title: XSS Test
    • content: [financoop_campaign id='<script>alert(document.domain)</script>']
    • action: editpost
    • post_type: post
    • _wpnonce: (Extracted from editor page)

Step 3: Trigger Execution

  • Navigate to the newly created post's permalink (or the preview link: /?p=POST_ID&preview=true).
  • The shortcode logic will fail to find a campaign with the script tag as its ID, trigger the error function, and reflect the script.

6. Test Data Setup

  1. User Creation: Create a user with the contributor role.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  2. Plugin Verification: Ensure forms-bridge is installed and active.
    wp plugin is-active forms-bridge || wp plugin activate forms-bridge
    

7. Expected Results

When the post is viewed:

  • The HTML source should contain: Forms Bridge Error: Campaign with ID <script>alert(document.domain)</script> was not found. (exact phrasing may vary).
  • A JavaScript alert box showing the document domain will appear in the browser context.

8. Verification Steps

  1. Database Check: Verify the shortcode is correctly stored in the wp_posts table.
    wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test' LIMIT 1;"
    
  2. Response Analysis: Use the http_request tool to fetch the post content and check for unescaped characters.
    # Check if <script> is returned literally and not as &lt;script&gt;
    grep -o "<script>alert(document.domain)</script>"
    

9. Alternative Approaches

If the id is rendered inside an HTML attribute (e.g., value="..."), the payload should be modified to break out of the attribute:

  • Attribute Breakout Payload: [financoop_campaign id='"><script>alert(1)</script>']
  • Event Handler Payload: [financoop_campaign id='x" onmouseover="alert(1)" style="width:1000px;height:1000px;display:block;"']

If the forms_bridge_financoop_shortcode_error function is only reachable under specific campaign settings, look for existing campaign IDs via wp-cli (if stored in options or custom tables) and try to bypass the validity check using an array or object if the plugin uses loose comparison.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Forms Bridge plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'id' attribute in the [financoop_campaign] shortcode. Due to a lack of sanitization and output escaping in the function handling shortcode errors, authenticated attackers with Contributor-level access can inject malicious JavaScript that executes when a user views the post.

Vulnerable Code

// Inferred from research plan and vulnerability description
function forms_bridge_financoop_shortcode_error($id) {
    // The $id parameter is reflected directly into the return string without escaping
    return "Forms Bridge Error: Campaign with ID $id was not found.";
}

---

// Inferred callback for the [financoop_campaign] shortcode
function financoop_campaign_shortcode_callback($atts) {
    $atts = shortcode_atts(array(
        'id' => '',
    ), $atts);

    $campaign_id = $atts['id'];

    // If the campaign ID is invalid or not found, it calls the vulnerable error function
    if (empty($campaign_id) || !financoop_get_campaign($campaign_id)) {
        return forms_bridge_financoop_shortcode_error($campaign_id);
    }
    
    // ... rest of logic
}

Security Fix

--- a/forms-bridge.php
+++ b/forms-bridge.php
@@ -10,5 +10,5 @@
 function forms_bridge_financoop_shortcode_error($id) {
-    return "Forms Bridge Error: Campaign with ID $id was not found.";
+    return "Forms Bridge Error: Campaign with ID " . esc_html($id) . " was not found.";
 }

Exploit Outline

The exploit is carried out by an authenticated user with at least Contributor-level privileges. 1. The attacker logs into the WordPress dashboard and creates a new post or page. 2. The attacker inserts the shortcode [financoop_campaign id="<script>alert(document.domain)</script>"] into the post content. 3. Because the provided 'id' does not correspond to a valid campaign, the plugin's internal logic triggers an error handling path. 4. The function forms_bridge_financoop_shortcode_error takes the raw 'id' attribute and reflects it into the page output without using WordPress escaping functions like esc_html(). 5. When the attacker previews the post or a site visitor views the published post, the script payload executes in their browser context.

Check if your site is affected.

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