[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fVQXYwqgSrki1IF7duROUZkgTb6KQ_jI9XRko6eQxcaQ":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-3239","strong-testimonials-authenticated-contributor-stored-cross-site-scripting-via-testimonialview-shortcode","Strong Testimonials \u003C= 3.2.21 - Authenticated (Contributor+) Stored Cross-Site Scripting via testimonial_view Shortcode","The Strong Testimonials plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's testimonial_view shortcode in all versions up to, and including, 3.2.21 due to insufficient input sanitization and output escaping on user supplied attributes. 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.","strong-testimonials",null,"\u003C=3.2.21","3.2.22","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-07 15:48:51","2026-04-08 04:27:19",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F88d769cd-bea8-42e4-80a8-a77c0699b50c?source=api-prod",1,[22,23,24,25],"includes\u002Fclass-strong-testimonials-render.php","includes\u002Ffunctions-template.php","readme.txt","strong-testimonials.php","researched",false,3,"## Vulnerability Summary\nThe **Strong Testimonials** plugin (versions \u003C= 3.2.21) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `testimonial_view` shortcode. The vulnerability exists because the plugin fails to sanitize or escape attributes provided by the user in the shortcode before rendering them in the HTML output or passing them to JavaScript localization functions. Specifically, attributes such as `id` or `view` are used to construct HTML elements and JavaScript variable names.\n\n## Attack Vector Analysis\n- **Shortcode:** `[testimonial_view]`\n- **Vulnerable Attribute:** `id` (and potentially `view`, `class`, or `title` depending on the template).\n- **Authentication Level:** Authenticated (**Contributor** or higher). Contributors can create posts and insert shortcodes.\n- **Preconditions:** The plugin must be active. A \"View\" does not necessarily need to exist for the attribute processing to trigger the vulnerability, but having one ensures the full rendering cycle.\n- **Payload Location:** The payload is stored in the `post_content` of a WordPress post\u002Fpage.\n\n## Code Flow\n1. **Entry Point:** A user with `edit_posts` capability (Contributor+) creates a post containing the shortcode: `[testimonial_view id='\u003Cpayload>']`.\n2. **Processing:** When the page is viewed, WordPress parses the shortcode. The `Strong_Testimonials_Render` class processes the attributes.\n3. **Attribute Storage:** In `includes\u002Fclass-strong-testimonials-render.php`, the `set_atts($atts)` method stores the user-supplied attributes in `$this->view_atts`.\n4. **Rendering Trigger:** The rendering process calls `WPMST()->render->prerender( $atts )` and `WPMST()->render->view_rendered()`.\n5. **Vulnerable Sink 1 (JS Variable Name):** The `view_rendered()` method calls `view_rendered_after()`, which executes `localize","The Strong Testimonials plugin is vulnerable to Stored Cross-Site Scripting via the 'id' attribute of the [testimonial_view] shortcode. Authenticated attackers with Contributor-level access can inject malicious payloads that break out of unquoted HTML data attributes, leading to arbitrary JavaScript execution in the context of a victim's browser.","\u002F\u002F includes\u002Fclass-strong-testimonials-render.php @ line 647\npublic function parse_view( $out, $pairs, $atts ) {\n\t\t\u002F\u002F Convert \"id\" to \"view\"\n\t\tif ( isset( $atts['id'] ) && $atts['id'] ) {\n\t\t\t$atts['view'] = $atts['id'];\n\t\t\tunset( $atts['id'] );\n\t\t} else {\n\n---\n\n\u002F\u002F includes\u002Ffunctions-template.php @ line 551\nfunction wpmtst_container_data() {\n\t$data_array = apply_filters( 'wpmtst_container_data', WPMST()->atts( 'container_data' ) );\n\tif ( $data_array ) {\n\t\t$data = '';\n\t\tforeach ( $data_array as $attr => $value ) {\n\t\t\t$data .= \" data-$attr=$value\";\n\t\t}\n\t\techo esc_attr( $data );\n\t}\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.21\u002Fincludes\u002Fclass-strong-testimonials-render.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.22\u002Fincludes\u002Fclass-strong-testimonials-render.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.21\u002Fincludes\u002Fclass-strong-testimonials-render.php\t2024-09-10 11:56:04.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.22\u002Fincludes\u002Fclass-strong-testimonials-render.php\t2026-02-26 10:04:58.000000000 +0000\n@@ -647,9 +647,15 @@\n \t * @return array\n \t *\u002F\n \tpublic function parse_view( $out, $pairs, $atts ) {\n-\t\t\u002F\u002F Convert \"id\" to \"view\"\n-\t\tif ( isset( $atts['id'] ) && $atts['id'] ) {\n-\t\t\t$atts['view'] = $atts['id'];\n+\t\t\u002F\u002F Convert \"id\" to \"view\" - sanitize to integer to prevent attribute breakout (security).\n+\t\tif ( isset( $atts['id'] ) && $atts['id'] !== '' ) {\n+\t\t\t$raw_id  = trim( (string) $atts['id'] );\n+\t\t\t$view_id = absint( $raw_id );\n+\t\t\t\u002F\u002F Reject non-numeric or malformed id (e.g. \"1 onmouseover=alert(1)\").\n+\t\t\tif ( $view_id \u003C 1 || $raw_id !== (string) $view_id ) {\n+\t\t\t\treturn array_merge( array( 'view_not_found' => 1 ), $atts );\n+\t\t\t}\n+\t\t\t$atts['view'] = $view_id;\n \t\t\tunset( $atts['id'] );\n \t\t} else {\n \t\t\treturn array_merge( array( 'view_not_found' => 1 ), $atts );\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.21\u002Fincludes\u002Ffunctions-template.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.22\u002Fincludes\u002Ffunctions-template.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.21\u002Fincludes\u002Ffunctions-template.php\t2026-01-13 10:10:46.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fstrong-testimonials\u002F3.2.22\u002Fincludes\u002Ffunctions-template.php\t2026-02-26 10:04:58.000000000 +0000\n@@ -551,12 +551,15 @@\n \n function wpmtst_container_data() {\n \t$data_array = apply_filters( 'wpmtst_container_data', WPMST()->atts( 'container_data' ) );\n-\tif ( $data_array ) {\n-\t\t$data = '';\n+\tif ( $data_array && is_array( $data_array ) ) {\n+\t\t$parts = array();\n \t\tforeach ( $data_array as $attr => $value ) {\n-\t\t\t$data .= \" data-$attr=$value\";\n+\t\t\t$attr    = sanitize_key( $attr );\n+\t\t\t$value   = esc_attr( (string) $value );\n+\t\t\t$parts[] = sprintf( ' data-%s=\"%s\"', $attr, $value );\n \t\t}\n-\t\techo esc_attr( $data );\n+\t\t\u002F\u002F phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Each part built from sanitize_key and esc_attr.\n+\t\techo implode( '', $parts );\n \t}\n }","1. An authenticated attacker with Contributor privileges (or higher) creates or edits a WordPress post.\n2. The attacker inserts a `[testimonial_view]` shortcode with a malicious `id` attribute, such as: `[testimonial_view id='1 onmouseover=alert(1)']`.\n3. The plugin processes this shortcode via the `Strong_Testimonials_Render` class. The `parse_view` method assigns the malicious payload to the `view` attribute without sanitization.\n4. When the page is rendered, the `wpmtst_container_data` function builds the container's HTML attributes. Because the plugin does not quote the attribute values (e.g., `data-view=1 onmouseover=alert(1)`), the space in the payload allows the attacker to inject a new HTML attribute (`onmouseover`).\n5. When any user, including an administrator, views the post and interacts with the testimonial container (e.g., hovers their mouse), the injected JavaScript executes.","gemini-3-flash-preview","2026-04-17 20:41:58","2026-04-17 20:42:49",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","3.2.21","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fstrong-testimonials\u002Ftags\u002F3.2.21","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fstrong-testimonials.3.2.21.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fstrong-testimonials\u002Ftags\u002F3.2.22","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fstrong-testimonials.3.2.22.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fstrong-testimonials\u002Ftags"]