Edit file File name : class-compatibility.php Content :<?php /** * Class used to manage backwards-compatibility of the package. * * @since 0.8.0 * * @package automattic/jetpack-waf */ namespace Automattic\Jetpack\Waf; use Jetpack_Options; /** * Defines methods for ensuring backwards compatibility. */ class Waf_Compatibility { /** * Returns the name for the IP allow list enabled/disabled option. * * @since 0.22.0 * * @return string */ private static function get_ip_allow_list_enabled_option_name() { /** * Patch: bootstrap script generated prior to 0.17.0 may have autoloaded Waf_Rules_Manager class during standalone mode execution. * * @see peb6dq-2HL-p2 */ if ( ! defined( 'Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME' ) ) { return 'jetpack_waf_ip_allow_list_enabled'; } return Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME; } /** * Returns the name for the IP block list enabled/disabled option. * * @since 0.22.0 * * @return string */ private static function get_ip_block_list_enabled_option_name() { /** * Patch: bootstrap script generated prior to 0.17.0 may have autoloaded Waf_Rules_Manager class during standalone mode execution. * * @see peb6dq-2HL-p2 */ if ( ! defined( 'Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME' ) ) { return 'jetpack_waf_ip_block_list_enabled'; } return Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME; } /** * Add compatibilty hooks * * @since 0.8.0 * * @return void */ public static function add_compatibility_hooks() { add_filter( 'default_option_' . Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME, __CLASS__ . '::default_option_waf_automatic_rules', 10, 3 ); add_filter( 'default_option_' . Waf_Initializer::NEEDS_UPDATE_OPTION_NAME, __CLASS__ . '::default_option_waf_needs_update', 10, 3 ); add_filter( 'default_option_' . Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME, __CLASS__ . '::default_option_waf_ip_allow_list', 10, 3 ); add_filter( 'option_' . Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME, __CLASS__ . '::filter_option_waf_ip_allow_list', 10, 1 ); add_filter( 'default_option_' . self::get_ip_allow_list_enabled_option_name(), __CLASS__ . '::default_option_waf_ip_allow_list_enabled', 10, 3 ); add_filter( 'default_option_' . self::get_ip_block_list_enabled_option_name(), __CLASS__ . '::default_option_waf_ip_block_list_enabled', 10, 3 ); } /** * Run compatibility migrations. * * Note that this method should be compatible with sites where * the request firewall is not active or not supported. * * @see Waf_Runner::is_supported_environment(). * * @since 0.11.0 * * @return void */ public static function run_compatibility_migrations() { self::migrate_brute_force_protection_ip_allow_list(); } /** * Provides a default value for sites that installed the WAF * before the automatic rules option was introduced. * * @since 0.9.0 * * @param mixed $default The default value to return if the option does not exist in the database. * @param string $option Option name. * @param bool $passed_default Was get_option() passed a default value. * * @return mixed The default value to return if the option does not exist in the database. */ public static function default_option_waf_automatic_rules( $default, $option, $passed_default ) { // Allow get_option() to override this default value if ( $passed_default ) { return $default; } return self::get_default_automatic_rules_option(); } /** * If the option is not available, use the WAF module status * to determine whether or not to run automatic rules. * * @since 0.9.0 * * @return bool The default value for automatic rules. */ public static function get_default_automatic_rules_option() { return Waf_Runner::is_enabled(); } /** * Provides a default value for sites that installed the WAF * before the NEEDS_UPDATE_OPTION_NAME option was added. * * @since 0.8.0 * * @param mixed $default The default value to return if the option does not exist in the database. * @param string $option Option name. * @param bool $passed_default Was get_option() passed a default value. * * @return mixed The default value to return if the option does not exist in the database. */ public static function default_option_waf_needs_update( $default, $option, $passed_default ) { // Allow get_option() to override this default value if ( $passed_default ) { return $default; } // If the option hasn't been added yet, the WAF needs to be updated. return true; } /** * Merge the WAF and Brute Force Protection IP allow lists. * * @since 0.11.0 * * @param string $waf_allow_list The WAF IP allow list. * @param array $brute_force_allow_list The Brute Force Protection IP allow list. Array of IP objects. * * @return string The merged IP allow list. */ public static function merge_ip_allow_lists( $waf_allow_list, $brute_force_allow_list ) { if ( empty( $brute_force_allow_list ) ) { return $waf_allow_list; } // Convert the IP objects to strings. $brute_force_allow_list = array_map( function ( $ip_object ) { if ( ! empty( $ip_object->range ) ) { return $ip_object->range_low . '-' . $ip_object->range_high; } return $ip_object->ip_address; }, $brute_force_allow_list ); $brute_force_allow_list_string = implode( "\n", $brute_force_allow_list ); if ( empty( $waf_allow_list ) ) { return $brute_force_allow_list_string; } // Return the lists merged into a single string. return "$waf_allow_list\n$brute_force_allow_list_string"; } /** * Migrate the brute force protection IP allow list option to the WAF option. * * @since 0.11.0 * * @return void */ public static function migrate_brute_force_protection_ip_allow_list() { // Get the allow list values directly from the database to avoid filters. $brute_force_allow_list = Jetpack_Options::get_raw_option( 'jetpack_protect_whitelist' ); $waf_allow_list = Jetpack_Options::get_raw_option( 'jetpack_waf_ip_allow_list' ); if ( ! empty( $brute_force_allow_list ) ) { if ( empty( $waf_allow_list ) ) { $waf_allow_list = ''; } // Merge the two allow lists. $merged_allow_list = self::merge_ip_allow_lists( $waf_allow_list, $brute_force_allow_list ); // Update the WAF IP allow list with the merged list. Jetpack_Options::update_raw_option( 'jetpack_waf_ip_allow_list', $merged_allow_list ); // Delete the old option if the update was successful. // Check the values directly as `update_raw_option()` returns false if the value hasn't changed. if ( Jetpack_Options::get_raw_option( 'jetpack_waf_ip_allow_list' ) === $merged_allow_list ) { delete_option( 'jetpack_protect_whitelist' ); } } } /** * Filter for Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME's option value. * Merges the deprecated IP allow list from the brute force protection module * with the existing option value, and flags that the WAF needs to be updated. * * @since 0.11.0 * * @param array $waf_allow_list The current value of the option. * * @return array The merged IP allow list. */ public static function filter_option_waf_ip_allow_list( $waf_allow_list ) { $brute_force_allow_list = Jetpack_Options::get_raw_option( 'jetpack_protect_whitelist', false ); if ( false !== $brute_force_allow_list ) { $waf_allow_list = self::merge_ip_allow_lists( $waf_allow_list, $brute_force_allow_list ); update_option( Waf_Initializer::NEEDS_UPDATE_OPTION_NAME, true ); } return $waf_allow_list; } /** * Default option for when the Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME option is not set. * * @param mixed $default The default value to return if the option does not exist in the database. * @param string $option Option name. * @param bool $passed_default Was get_option() passed a default value. * * @return mixed The default value to return if the option does not exist in the database. */ public static function default_option_waf_ip_allow_list( $default, $option, $passed_default ) { // Allow get_option() to override this default value if ( $passed_default ) { return $default; } $waf_allow_list = ''; // If the brute force option exists, use that and flag that the WAF needs to be updated. $brute_force_allow_list = Jetpack_Options::get_raw_option( 'jetpack_protect_whitelist', false ); if ( false !== $brute_force_allow_list ) { $waf_allow_list = self::merge_ip_allow_lists( $waf_allow_list, $brute_force_allow_list ); update_option( Waf_Initializer::NEEDS_UPDATE_OPTION_NAME, true ); } return $waf_allow_list; } /** * Check if the brute force protection code is being run by an older version of Jetpack (< 12.0). * * @since 0.11.1 * * @return bool */ public static function is_brute_force_running_in_jetpack() { return defined( 'JETPACK__VERSION' ) && version_compare( JETPACK__VERSION, '12', '<' ); } /** * Default the allow list enabled option to the value of the generic IP lists enabled option it replaced. * * @since 0.17.0 * * @param mixed $default The default value to return if the option does not exist in the database. * @param string $option Option name. * @param bool $passed_default Was get_option() passed a default value. * * @return mixed The default value to return if the option does not exist in the database. */ public static function default_option_waf_ip_allow_list_enabled( $default, $option, $passed_default ) { // Allow get_option() to override this default value if ( $passed_default ) { return $default; } // If the deprecated IP lists option was set to false, disable the allow list. // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. $deprecated_option = Jetpack_Options::get_raw_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, true ); if ( ! $deprecated_option ) { return false; } // If the allow list is empty, disable the allow list. if ( ! Jetpack_Options::get_raw_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME ) ) { return false; } // Default to enabling the allow list. return true; } /** * Default the block list enabled option to the value of the generic IP lists enabled option it replaced. * * @since 0.17.0 * * @param mixed $default The default value to return if the option does not exist in the database. * @param string $option Option name. * @param bool $passed_default Was get_option() passed a default value. * * @return mixed The default value to return if the option does not exist in the database. */ public static function default_option_waf_ip_block_list_enabled( $default, $option, $passed_default ) { // Allow get_option() to override this default value if ( $passed_default ) { return $default; } // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. return Jetpack_Options::get_raw_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, false ); } } Save