$version ); } return array(); } public static function affected( array $inventory ): bool { $v = $inventory['litespeed-cache'] ?? null; return is_string( $v ) && preg_match( '/^[0-9]+(?:\.[0-9]+){1,3}$/D', $v ) && version_compare( $v, '1.9.1', '>=' ) && version_compare( $v, '6.3.0.1', '<=' ); } public static function inspect( array $inventory, array $cookies ): array { // Presence is intentionally enough: non-empty arrays and alternate string encodings must not bypass it. return self::affected( $inventory ) && array_key_exists( 'litespeed_role', $cookies ) && array_key_exists( 'litespeed_hash', $cookies ) ? array( array( 'rule' => self::RULE, 'parameter' => 'cookie.litespeed_role' ) ) : array(); } public static function status(): array { return array( 'rule' => self::RULE, 'cve' => 'CVE-2024-28000', 'affected_installed' => self::affected( self::inventory() ), 'mode' => Firewall::configuration()['mode'], 'range' => 'LiteSpeed Cache 1.9.1–6.3.0.1', 'source' => 'https://www.wordfence.com/blog/2024/08/over-5000000-site-owners-affected-by-critical-privilege-escalation-vulnerability-patched-in-litespeed-cache-plugin/', 'limitation' => 'Blocks the vulnerable cookie-based role-simulation entry point before normal theme setup. Legitimate role-simulation crawling also stops while blocking applies. Update LiteSpeed Cache; this single mitigation is not a maintained virtual-patch catalog and does not cover separate vulnerabilities or code that executes earlier.' ); } public static function guard(): void { if ( ( defined( 'WP_CLI' ) && WP_CLI ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) || ( defined( 'ANTIVIRUS_AI_DISABLE_FIREWALL' ) && ANTIVIRUS_AI_DISABLE_FIREWALL ) ) { return; } $config = Firewall::configuration(); if ( 'off' === $config['mode'] ) { return; } // Only the two attack-related names matter. Do not import authentication or cookie values. $cookies = array(); if ( array_key_exists( 'litespeed_role', $_COOKIE ) ) { $cookies['litespeed_role'] = true; } if ( array_key_exists( 'litespeed_hash', $_COOKIE ) ) { $cookies['litespeed_hash'] = true; } $matches = self::inspect( self::inventory(), $cookies ); $block = false; foreach ( $matches as $match ) { $method = Firewall::requestMethod(); $route = Firewall::route( Firewall::requestUri() ); $excepted = Firewall::excepted( $match, $route, $method, $config['exceptions'] ); Firewall::record( $match['rule'], $excepted ? 'excepted' : $config['mode'], $method, $route, $match['parameter'] ); $block = $block || ( ! $excepted && 'block' === $config['mode'] ); } if ( $block ) { nocache_headers(); wp_die( esc_html__( 'This request uses a vulnerable component feature temporarily blocked by site protection. Ask the site owner to update the affected plugin.', 'shieldlume-security' ), esc_html__( 'Request blocked', 'shieldlume-security' ), array( 'response' => 403 ) ); } } }