[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fg8cuIoMXfh03yqGuxLngxK7G9wXUSClchcUkauvtTqM":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-1379","http-headers-authenticated-administrator-stored-cross-site-scripting-via-custom-headers-plugin-setting","HTTP Headers \u003C= 1.19.2 - Authenticated (Administrator+) Stored Cross-Site Scripting via 'Custom Headers' Plugin Setting","The HTTP Headers plugin for WordPress is vulnerable to Stored Cross-Site Scripting via admin settings in all versions up to, and including, 1.19.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level permissions and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.","http-headers",null,"\u003C=1.19.2","medium",4.4,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:H\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:13:16","2026-05-04 15:40:39",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F02e63068-02a8-4106-b64e-430c24815e55?source=api-prod",[],"researched",false,3,"# Research Plan: CVE-2026-1379 - Authenticated Stored XSS in HTTP Headers\n\n## 1. Vulnerability Summary\nThe **HTTP Headers** plugin (\u003C= 1.19.2) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the \"Custom Headers\" setting. The plugin allows administrators to define custom HTTP headers to be sent by the server. However, it fails to sufficiently sanitize the input when saving these headers and fails to escape the output when displaying them back in the administrative interface. \n\nIn a standard WordPress installation, Administrators have the `unfiltered_html` capability, making this \"intended functionality.\" However, in **Multi-site** environments or installations where `DISALLOW_UNFILTERED_HTML` is defined as `true`, this vulnerability allows an Administrator to bypass those restrictions and inject malicious scripts that execute in the context of other users (including Super Admins) who visit the plugin's settings page.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** WordPress Admin Settings page for the plugin, typically `wp-admin\u002Foptions-general.php?page=http-headers` or a specific sub-page for \"Custom\".\n*   **Vulnerable Parameter:** Likely a POST parameter named `custom_headers` or similar, nested within the plugin's options array.\n*   **Authentication:** Authenticated, Administrator+ level permissions.\n*   **Preconditions:** \n    1.  The plugin `http-headers` (\u003C= 1.19.2) must be active.\n    2.  `unfiltered_html` must be disabled (common in Multi-site or via `define('DISALLOW_UNFILTERED_HTML', true);` in `wp-config.php`).\n\n## 3. Code Flow (Inferred)\n1.  **Entry Point:** The Administrator navigates to the plugin settings and submits a form to save custom headers.\n2.  **Processing:** The request hits `wp-admin\u002Foptions.php` (if using the Settings API) or a custom `admin_init` hook. The plugin receives the array of custom headers.\n3.  **Storage:** The plugin calls `update_option()` to save the custom headers into the database (likely under an option name like `http_headers_settings` or `http_headers_custom`).\n4.  **Sink (Output):** When any administrator visits the \"Custom Headers\" configuration tab, the plugin retrieves the saved option and echoes it into the HTML value attribute of an input field or within a table row without using `esc_attr()` or `esc_html()`.\n5.  **Execution:** The injected script (e.g., `\">\u003Cscript>alert(1)\u003C\u002Fscript>`) breaks out of the HTML attribute and executes in the browser.\n\n## 4. Nonce Acquisition Strategy\nThe plugin likely uses the standard WordPress Settings API or a custom form on an admin page. \n\n1.  **Identify the Page:** Use `wp-cli` to find the settings page slug:\n    `wp admin-menu list | grep \"HTTP Headers\"`\n2.  **Navigate and Extract:**\n    *   Use `browser_navigate` to go to the identified settings page (e.g., `\u002Fwp-admin\u002Foptions-general.php?page=http-headers`).\n    *   The form will contain a hidden `_wpnonce` field.\n    *   **Action String:** If the plugin uses `settings_fields('http_headers_group')`, the nonce action will be `http_headers_group-options`.\n    *   **JS Extraction:** \n        ```javascript\n        browser_eval(\"document.querySelector('input[name=\\\"_wpnonce\\\"]')?.value\")\n        ```\n\n## 5. Exploitation Strategy\n1.  **Setup Environment:** Ensure `DISALLOW_UNFILTERED_HTML` is set to `true` in `wp-config.php`.\n2.  **Identify Parameter Name:** Inspect the settings page to find the exact name of the custom header input field. (Inferred: `http_headers_custom[0][value]` or similar).\n3.  **Payload Construction:**\n    *   Simple: `\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n    *   Breaking out of an input: `\">\u003Cimg src=x onerror=alert(1)>`\n4.  **HTTP Request (Playwright):**\n    Submit a POST request to `wp-admin\u002Foptions.php` (if Settings API) or the plugin's own admin page.\n\n    **Example Request:**\n    ```http\n    POST \u002Fwp-admin\u002Foptions.php HTTP\u002F1.1\n    Content-Type: application\u002Fx-www-form-urlencoded\n\n    option_page=http_headers_settings_group&\n    action=update&\n    _wpnonce=[EXTRACTED_NONCE]&\n    http_headers_settings[custom_headers][0][name]=X-XSS-Test&\n    http_headers_settings[custom_headers][0][value]=%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E\n    ```\n\n5.  **Trigger:** Navigate back to the \"Custom Headers\" settings page to trigger the stored payload.\n\n## 6. Test Data Setup\n1.  **Plugin Installation:** `wp plugin install http-headers --version=1.19.2 --activate`\n2.  **Config Change:** Add `define( 'DISALLOW_UNFILTERED_HTML', true );` to `wp-config.php` using a file write tool or `sed`.\n3.  **User Creation:** Ensure an administrator user exists (e.g., `admin` \u002F `password`).\n4.  **Page Visit:** Visit the settings page once to ensure default options are initialized.\n\n## 7. Expected Results\n*   The POST request should return a `302 Redirect` back to the settings page with `settings-updated=true`.\n*   Upon navigating to the \"Custom Headers\" tab, the browser should execute the `alert(1)` script.\n*   The HTML source of the page should show the unescaped payload: `\u003Cinput ... value=\"\">\u003Cscript>alert(1)\u003C\u002Fscript>\">`.\n\n## 8. Verification Steps\n1.  **Database Check:** Use `wp-cli` to verify the payload is stored in the database:\n    `wp option get http_headers_settings --format=json` (or the specific option name found during research).\n2.  **DOM Check:** Use `browser_eval` to check for the presence of the injected script:\n    `browser_eval(\"!!document.querySelector('script')\")`\n3.  **Visual Confirmation:** Capture a screenshot of the alert\u002Finjected element using the `screenshot` tool.\n\n## 9. Alternative Approaches\n*   **AJAX Entry Point:** If the plugin doesn't use `options.php`, check for `wp_ajax_save_http_headers` hooks in the source.\n*   **Header Injection (Frontend):** If the plugin also renders these headers in the site frontend (as actual HTTP headers), test if it's possible to inject a `Set-Cookie` or `Refresh` header to perform session fixation or redirects, though the primary vulnerability is XSS in the admin UI.\n*   **Attribute Breakout:** If the input is inside a complex JavaScript structure, use a JSON-breaking payload: `\\\";alert(1)\u002F\u002F`.","The HTTP Headers plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'Custom Headers' setting in versions up to 1.19.2. This occurs because the plugin fails to sanitize user-provided header values before storage and fails to escape them when displaying them back in the administrative interface, allowing attackers to bypass 'unfiltered_html' restrictions in Multi-site environments.","\u002F\u002F File: http-headers\u002Fpages\u002Fcustom.php (Inferred based on plugin structure and research plan)\n\u002F\u002F The plugin iterates through custom headers and echoes the 'value' key directly into an input attribute without escaping.\n\nfor ($i = 0; $i \u003C count($http_headers_custom); $i++) {\n    echo '\u003Ctr>';\n    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][name]\" type=\"text\" value=\"' . $http_headers_custom[$i]['name'] . '\" \u002F>\u003C\u002Ftd>';\n    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][value]\" type=\"text\" value=\"' . $http_headers_custom[$i]['value'] . '\" \u002F>\u003C\u002Ftd>';\n    echo '\u003C\u002Ftr>';\n}","--- a\u002Fhttp-headers\u002Fpages\u002Fcustom.php\n+++ b\u002Fhttp-headers\u002Fpages\u002Fcustom.php\n@@ -3,6 +3,6 @@\n for ($i = 0; $i \u003C count($http_headers_custom); $i++) {\n     echo '\u003Ctr>';\n-    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][name]\" type=\"text\" value=\"' . $http_headers_custom[$i]['name'] . '\" \u002F>\u003C\u002Ftd>';\n-    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][value]\" type=\"text\" value=\"' . $http_headers_custom[$i]['value'] . '\" \u002F>\u003C\u002Ftd>';\n+    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][name]\" type=\"text\" value=\"' . esc_attr($http_headers_custom[$i]['name']) . '\" \u002F>\u003C\u002Ftd>';\n+    echo '\u003Ctd>\u003Cinput name=\"http_headers_custom[' . $i . '][value]\" type=\"text\" value=\"' . esc_attr($http_headers_custom[$i]['value']) . '\" \u002F>\u003C\u002Ftd>';\n     echo '\u003C\u002Ftr>';\n }","1. Authentication: Log in to the WordPress dashboard as an Administrator. This exploit is particularly relevant on Multi-site installations or where 'unfiltered_html' is disabled.\n2. Nonce Acquisition: Navigate to the HTTP Headers settings page (Settings > HTTP Headers) and click the 'Custom' tab. Extract the security nonce from the form (e.g., using `document.querySelector('input[name=\"_wpnonce\"]').value`).\n3. Payload Injection: Construct a POST request to `wp-admin\u002Foptions.php` that includes the extracted nonce and an XSS payload (e.g., `\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>`) in the `http_headers_custom[0][value]` parameter.\n4. Storage: The WordPress Settings API saves the malicious payload into the `http_headers_custom` option in the database.\n5. Execution: The payload is triggered whenever an administrator visits the 'Custom' headers configuration sub-page, as the plugin echoes the stored value directly into the HTML without sanitization or attribute escaping.","gemini-3-flash-preview","2026-04-27 13:53:05","2026-04-27 13:53:22",{"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\u002Fhttp-headers\u002Ftags"]