diff --git a/projects/packages/waf/changelog/waf-ip-list-additional-compatibility b/projects/packages/waf/changelog/waf-ip-list-additional-compatibility new file mode 100644 index 0000000000000..6792100d7a7d2 --- /dev/null +++ b/projects/packages/waf/changelog/waf-ip-list-additional-compatibility @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Improved backwards/cross compatibility of option deprecation related to IP block/allow lists. + + diff --git a/projects/packages/waf/src/class-compatibility.php b/projects/packages/waf/src/class-compatibility.php index 8e70fa2ec8ebd..1f818cc23e822 100644 --- a/projects/packages/waf/src/class-compatibility.php +++ b/projects/packages/waf/src/class-compatibility.php @@ -244,23 +244,23 @@ public static function is_brute_force_running_in_jetpack() { * @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 = get_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, true ); + $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 ( ! get_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME ) ) { + if ( ! Jetpack_Options::get_raw_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME ) ) { return false; } - // Allow get_option() to override this default value - if ( $passed_default ) { - return $default; - } - // Default to enabling the allow list. return true; } @@ -283,6 +283,6 @@ public static function default_option_waf_ip_block_list_enabled( $default, $opti } // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - return get_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, false ); + return Jetpack_Options::get_raw_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, false ); } } diff --git a/projects/packages/waf/src/class-rest-controller.php b/projects/packages/waf/src/class-rest-controller.php index d0a873c86e7fe..e2433a1f96e10 100644 --- a/projects/packages/waf/src/class-rest-controller.php +++ b/projects/packages/waf/src/class-rest-controller.php @@ -103,14 +103,17 @@ public static function waf() { public static function update_waf( $request ) { // Automatic Rules Enabled if ( isset( $request[ Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME ] ) ) { - update_option( Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME, (bool) $request->get_param( Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME ) ); + update_option( Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME, $request->get_param( Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME ) ? '1' : '' ); } - // IP Lists Enabled - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - if ( isset( $request[ Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME ] ) ) { - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - update_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, (bool) $request->get_param( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME ) ); + /** + * IP Lists Enabled + * + * @deprecated $next-version$ This is a legacy option maintained here for backwards compatibility. + */ + if ( isset( $request['jetpack_waf_ip_list'] ) ) { + update_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME, $request['jetpack_waf_ip_list'] ? '1' : '' ); + update_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME, $request['jetpack_waf_ip_list'] ? '1' : '' ); } // IP Block List @@ -118,7 +121,7 @@ public static function update_waf( $request ) { update_option( Waf_Rules_Manager::IP_BLOCK_LIST_OPTION_NAME, $request[ Waf_Rules_Manager::IP_BLOCK_LIST_OPTION_NAME ] ); } if ( isset( $request[ Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ] ) ) { - update_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME, $request[ Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ] ); + update_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME, $request[ Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ] ? '1' : '' ); } // IP Allow List @@ -126,27 +129,27 @@ public static function update_waf( $request ) { update_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME, $request[ Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME ] ); } if ( isset( $request[ Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ] ) ) { - update_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME, $request[ Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ] ); + update_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME, $request[ Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ] ? '1' : '' ); } // Share Data if ( isset( $request[ Waf_Runner::SHARE_DATA_OPTION_NAME ] ) ) { // If a user disabled the regular share we should disable the debug share data option. - if ( false === $request[ Waf_Runner::SHARE_DATA_OPTION_NAME ] ) { - update_option( Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME, false ); + if ( ! $request[ Waf_Runner::SHARE_DATA_OPTION_NAME ] ) { + update_option( Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME, '' ); } - update_option( Waf_Runner::SHARE_DATA_OPTION_NAME, (bool) $request[ Waf_Runner::SHARE_DATA_OPTION_NAME ] ); + update_option( Waf_Runner::SHARE_DATA_OPTION_NAME, $request[ Waf_Runner::SHARE_DATA_OPTION_NAME ] ? '1' : '' ); } // Share Debug Data if ( isset( $request[ Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME ] ) ) { // If a user toggles the debug share we should enable the regular share data option. - if ( true === $request[ Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME ] ) { - update_option( Waf_Runner::SHARE_DATA_OPTION_NAME, true ); + if ( $request[ Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME ] ) { + update_option( Waf_Runner::SHARE_DATA_OPTION_NAME, 1 ); } - update_option( Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME, (bool) $request[ Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME ] ); + update_option( Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME, $request[ Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME ] ? '1' : '' ); } // Brute Force Protection diff --git a/projects/packages/waf/src/class-waf-rules-manager.php b/projects/packages/waf/src/class-waf-rules-manager.php index bada7d0f4ed3f..d657538138a12 100644 --- a/projects/packages/waf/src/class-waf-rules-manager.php +++ b/projects/packages/waf/src/class-waf-rules-manager.php @@ -53,15 +53,13 @@ public static function add_hooks() { // Re-activate the WAF any time an option is added or updated. add_action( 'add_option_' . self::AUTOMATIC_RULES_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); add_action( 'update_option_' . self::AUTOMATIC_RULES_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - add_action( 'add_option_' . self::IP_LISTS_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - add_action( 'update_option_' . self::IP_LISTS_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); - add_action( 'add_option_' . self::IP_ALLOW_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); add_action( 'add_option_' . self::IP_ALLOW_LIST_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); + add_action( 'update_option_' . self::IP_ALLOW_LIST_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); + add_action( 'add_option_' . self::IP_ALLOW_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); add_action( 'update_option_' . self::IP_ALLOW_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); - add_action( 'add_option_' . self::IP_BLOCK_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); add_action( 'add_option_' . self::IP_BLOCK_LIST_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); + add_action( 'update_option_' . self::IP_BLOCK_LIST_ENABLED_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); + add_action( 'add_option_' . self::IP_BLOCK_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); add_action( 'update_option_' . self::IP_BLOCK_LIST_OPTION_NAME, array( static::class, 'reactivate_on_rules_option_change' ), 10, 0 ); // Register the cron job. add_action( 'jetpack_waf_rules_update_cron', array( static::class, 'update_rules_cron' ) ); diff --git a/projects/packages/waf/src/class-waf-runner.php b/projects/packages/waf/src/class-waf-runner.php index 3577de39a6ea1..dcbc5f533c746 100644 --- a/projects/packages/waf/src/class-waf-runner.php +++ b/projects/packages/waf/src/class-waf-runner.php @@ -179,7 +179,7 @@ public static function get_config() { * @deprecated $next-version$ */ // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME => get_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME ), + Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME => get_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ) || get_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ), ); } diff --git a/projects/packages/waf/tests/php/integration/test-waf-compatibility.php b/projects/packages/waf/tests/php/integration/test-waf-compatibility.php index a8670eade18ab..b4026996c21a7 100644 --- a/projects/packages/waf/tests/php/integration/test-waf-compatibility.php +++ b/projects/packages/waf/tests/php/integration/test-waf-compatibility.php @@ -194,6 +194,27 @@ public function testAutomaticRulesOptionInheritsFromModuleStatus() { * Test the default options for the IP allow and block lists. */ public function testIpListsDefaultOptions() { + $filter_option = function ( $option, $value ) { + return function ( $result, $query ) use ( $option, $value ) { + global $wpdb; + + if ( $query === "SELECT option_value FROM $wpdb->options WHERE option_name = '$option' LIMIT 1" ) { + return array( + (object) array( + 'option_value' => serialize( $value ), + ), + ); + } + + return $result; + }; + }; + // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. + $filter_ip_list_option_true = $filter_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, true ); + // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. + $filter_ip_list_option_false = $filter_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, false ); + $filter_ip_allow_list_content = $filter_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME, '1.2.3.4' ); + // Enable the WAF module. Waf_Runner::enable(); @@ -202,24 +223,20 @@ public function testIpListsDefaultOptions() { $this->assertFalse( get_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ) ); // Add content to the allow list. - update_option( Waf_Rules_Manager::IP_ALLOW_LIST_OPTION_NAME, '1.2.3.4' ); + add_filter( 'wordbless_wpdb_query_results', $filter_ip_allow_list_content, 10, 2 ); $this->assertTrue( get_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ) ); $this->assertFalse( get_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ) ); - // Toggle the old generic option from true to false. - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - update_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, true ); - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - update_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, false ); + add_filter( 'wordbless_wpdb_query_results', $filter_ip_list_option_false, 10, 2 ); // Options default to false when the old generic option is set to false. $this->assertFalse( get_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ) ); $this->assertFalse( get_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ) ); // Set the old generic option to true. - // @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility. - update_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME, true ); + remove_filter( 'wordbless_wpdb_query_results', $filter_ip_list_option_false, 10, 2 ); + add_filter( 'wordbless_wpdb_query_results', $filter_ip_list_option_true, 10, 2 ); // Options default to true when the old generic option is set to true. $this->assertTrue( get_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ) );