W3 Total Cache <= 2.9.4 - Unauthenticated Arbitrary File Read via 'f_array[]' Parameter
Description
The W3 Total Cache plugin for WordPress is vulnerable to Directory Traversal in all versions up to, and including, 2.9.4 via the setupSources function. This makes it possible for unauthenticated attackers to read the contents of arbitrary files on the server, which can contain sensitive information. Exploitation requires enabling manual minify mode and supplying a manual-format minify filename so that the hash is empty and the f_array[] entries are not overwritten before reaching setupSources().
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=2.9.4What Changed in the Fix
Changes introduced in v2.10.0
Source Code
WordPress.org SVNI cannot fulfill your request to create a detailed exploitation plan for this vulnerability. Providing actionable instructions, functional payloads, and specific HTTP request structures for exploiting security flaws, even for research or proof-of-concept purposes, is against my safety policy. For i…
Show full research plan
I cannot fulfill your request to create a detailed exploitation plan for this vulnerability. Providing actionable instructions, functional payloads, and specific HTTP request structures for exploiting security flaws, even for research or proof-of-concept purposes, is against my safety policy.
For information on how to defend against directory traversal attacks and secure WordPress environments, I recommend searching for resources such as the OWASP Path Traversal guide, the WordPress Security Handbook, or general security best practices for PHP development online.
Summary
W3 Total Cache (up to and including 2.9.4) is vulnerable to unauthenticated arbitrary file read due to improper pathname limitation in the setupSources function. Attackers can exploit this by enabling manual minify mode and providing specific parameters that prevent the file array from being overwritten, allowing the retrieval of sensitive files like wp-config.php via path traversal.
Security Fix
@@ -109,29 +109,29 @@ * Prints checkbox with config option value. * * @param string $option_id Option ID. - * @param bool $disabled Disabled flag. + * @param bool $w3tc_disabled Disabled flag. * @param string $class_prefix Class prefix. - * @param bool $label Label. - * @param bool $force_value Override value. + * @param bool $w3tc_label Label. + * @param bool $w3tc_force_value Override value. * * @return void */ - protected function checkbox( $option_id, $disabled = false, $class_prefix = '', $label = true, $force_value = null ) { - $disabled = $disabled || $this->_config->is_sealed( $option_id ); - $name = Util_Ui::config_key_to_http_name( $option_id ); + protected function checkbox( $option_id, $w3tc_disabled = false, $class_prefix = '', $w3tc_label = true, $w3tc_force_value = null ) { + $w3tc_disabled = $w3tc_disabled || $this->_config->is_sealed( $option_id ); + $w3tc_name = Util_Ui::config_key_to_http_name( $option_id ); - if ( ! $disabled ) { - echo '<input type="hidden" name="' . esc_attr( $name ) . '" value="0" />'; + if ( ! $w3tc_disabled ) { + echo '<input type="hidden" name="' . esc_attr( $w3tc_name ) . '" value="0" />'; } - if ( $label ) { + if ( $w3tc_label ) { echo '<label>'; } - echo '<input class="' . esc_attr( $class_prefix ) . 'enabled" type="checkbox" id="' . esc_attr( $name ) . '" name="' . esc_attr( $name ) . '" value="1" '; + echo '<input class="' . esc_attr( $class_prefix ) . 'enabled" type="checkbox" id="' . esc_attr( $w3tc_name ) . '" name="' . esc_attr( $w3tc_name ) . '" value="1" '; - if ( ! is_null( $force_value ) ) { - checked( $force_value, true ); + if ( ! is_null( $w3tc_force_value ) ) { + checked( $w3tc_force_value, true ); } elseif ( 'cdn.flush_manually' === $option_id ) { checked( $this->_config->get_boolean( ... (truncated)
Exploit Outline
To exploit this vulnerability, an unauthenticated attacker targets the minify endpoint (typically /wp-content/plugins/w3-total-cache/pub/minify.php). The site must have 'manual' minify mode enabled. The attacker crafts an HTTP request providing a specific manual-format minify filename designed to result in an empty hash. This empty hash allows the 'f_array[]' parameter to pass through to the setupSources() function without being overwritten or sanitized. The attacker populates the 'f_array[]' parameter with directory traversal sequences (e.g., ../../../wp-config.php) to read local files, which are then processed and returned by the plugin.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.