updated plugin Jetpack Protect version 1.4.2

This commit is contained in:
2023-10-22 22:21:06 +00:00
committed by Gitium
parent f512d25847
commit f07dfae114
242 changed files with 6494 additions and 1502 deletions

View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<ruleset>
<!-- Some code here runs outside of WordPress code. -->
<!-- TODO: Split that by directory or something so we can do this only for the non-WordPress code. -->
<rule ref="Jetpack-Compat-NoWP" />
</ruleset>

View File

@ -5,6 +5,48 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.11.13] - 2023-10-10
### Fixed
- Escape email address when output in HTML. [#33536]
## [0.11.12] - 2023-09-28
### Changed
- Minor internal updates.
## [0.11.11] - 2023-09-19
- Minor internal updates.
## [0.11.10] - 2023-09-11
### Changed
- General: remove backwards-compatible functions now that package relies on WordPress 6.2. [#32772]
## [0.11.9] - 2023-08-28
### Changed
- Updated package dependencies. [#32605]
## [0.11.8] - 2023-07-18
### Changed
- Add support for running brute force protection in environments that otherwise do not support the WAF. [#31761]
- Minor performance improvements. [#31684]
## [0.11.7] - 2023-07-17
### Changed
- Add support for non-empty server https values. [#31688]
## [0.11.6] - 2023-05-22
### Added
- Add integration tests for unsupported environments [#30544]
### Fixed
- Fix Brute force protection activation when WAF unset [#30544]
- Fix unavailable endpoint when WAF module is disabled [#30487]
- Multisite: avoid errors when the package is used in the Protect plugin instead of the Jetpack plugin. [#30767]
## [0.11.5] - 2023-05-15
### Changed
- Internal updates.
## [0.11.4] - 2023-04-27
### Added
- Fix hardblock issue if user only has Protect installed [#30278]
@ -193,6 +235,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Core: do not ship .phpcs.dir.xml in production builds.
[0.11.13]: https://github.com/Automattic/jetpack-waf/compare/v0.11.12...v0.11.13
[0.11.12]: https://github.com/Automattic/jetpack-waf/compare/v0.11.11...v0.11.12
[0.11.11]: https://github.com/Automattic/jetpack-waf/compare/v0.11.10...v0.11.11
[0.11.10]: https://github.com/Automattic/jetpack-waf/compare/v0.11.9...v0.11.10
[0.11.9]: https://github.com/Automattic/jetpack-waf/compare/v0.11.8...v0.11.9
[0.11.8]: https://github.com/Automattic/jetpack-waf/compare/v0.11.7...v0.11.8
[0.11.7]: https://github.com/Automattic/jetpack-waf/compare/v0.11.6...v0.11.7
[0.11.6]: https://github.com/Automattic/jetpack-waf/compare/v0.11.5...v0.11.6
[0.11.5]: https://github.com/Automattic/jetpack-waf/compare/v0.11.4...v0.11.5
[0.11.4]: https://github.com/Automattic/jetpack-waf/compare/v0.11.3...v0.11.4
[0.11.3]: https://github.com/Automattic/jetpack-waf/compare/v0.11.2...v0.11.3
[0.11.2]: https://github.com/Automattic/jetpack-waf/compare/v0.11.1...v0.11.2

View File

@ -4,15 +4,15 @@
"type": "jetpack-library",
"license": "GPL-2.0-or-later",
"require": {
"automattic/jetpack-connection": "^1.51.7",
"automattic/jetpack-constants": "^1.6.22",
"automattic/jetpack-ip": "^0.1.2",
"automattic/jetpack-status": "^1.17.0",
"automattic/jetpack-connection": "^1.58.1",
"automattic/jetpack-constants": "^1.6.23",
"automattic/jetpack-ip": "^0.1.6",
"automattic/jetpack-status": "^1.18.5",
"wikimedia/aho-corasick": "^1.0"
},
"require-dev": {
"yoast/phpunit-polyfills": "1.0.4",
"automattic/jetpack-changelogger": "^3.3.2",
"yoast/phpunit-polyfills": "1.1.0",
"automattic/jetpack-changelogger": "^3.3.11",
"automattic/wordbless": "@dev"
},
"suggest": {

View File

@ -232,7 +232,7 @@ class Brute_Force_Protection_Blocked_Login_Page {
return true;
}
if ( ! isset( $_GET['validate_jetpack_protect_recovery'], $_GET['user_id'] ) ) { // phpcs:ignore: WordPress.Security.NonceVerification.Recommended -- no changes made if this isn't set.
if ( ! isset( $_GET['validate_jetpack_protect_recovery'] ) || ! isset( $_GET['user_id'] ) ) { // phpcs:ignore: WordPress.Security.NonceVerification.Recommended -- no changes made if this isn't set.
return false;
}
@ -366,7 +366,7 @@ class Brute_Force_Protection_Blocked_Login_Page {
if ( self::HTTP_STATUS_CODE_TOO_MANY_REQUESTS === $code ) {
// translators: email address the recovery instructions were sent to.
return new WP_Error( 'email_already_sent', sprintf( __( 'Recovery instructions were sent to %s. Check your inbox!', 'jetpack-waf' ), $this->email_address ) );
return new WP_Error( 'email_already_sent', sprintf( __( 'Recovery instructions were sent to %s. Check your inbox!', 'jetpack-waf' ), esc_html( $this->email_address ) ) );
} elseif ( is_wp_error( $result ) || empty( $result ) || isset( $result->error ) ) {
return new WP_Error( 'email_send_error', __( 'Oops, we were unable to send a recovery email. Try again.', 'jetpack-waf' ) );
}

View File

@ -176,6 +176,5 @@ if ( ! class_exists( 'Brute_Force_Protection_Math_Authenticate' ) ) {
</div>
<?php
}
}
}

View File

@ -212,6 +212,10 @@ class Brute_Force_Protection {
* @return bool
*/
public static function enable() {
// Return true if already enabled.
if ( self::is_enabled() ) {
return true;
}
return ( new Modules() )->activate( 'protect', false, false );
}
@ -221,6 +225,10 @@ class Brute_Force_Protection {
* @return bool
*/
public static function disable() {
// Return true if already disabled.
if ( ! self::is_enabled() ) {
return true;
}
return ( new Modules() )->deactivate( 'protect' );
}
@ -276,7 +284,16 @@ class Brute_Force_Protection {
require_once ABSPATH . '/wp-admin/includes/plugin.php';
}
if ( ! is_plugin_active_for_network( plugin_basename( JETPACK__PLUGIN_FILE ) ) ) {
// This warning is only relevant if either Jetpack or Jetpack Protect is active.
if ( defined( 'JETPACK__PLUGIN_FILE' ) ) {
$plugin_root_file = JETPACK__PLUGIN_FILE;
} elseif ( defined( 'JETPACK_PROTECT_ROOT_FILE' ) ) {
$plugin_root_file = JETPACK_PROTECT_ROOT_FILE;
} else {
return;
}
if ( ! is_plugin_active_for_network( plugin_basename( $plugin_root_file ) ) ) {
add_action( 'load-index.php', array( $this, 'prepare_jetpack_protect_multisite_notice' ) );
add_action( 'wp_ajax_jetpack-protect-dismiss-multisite-banner', array( $this, 'ajax_dismiss_handler' ) );
}
@ -319,7 +336,15 @@ class Brute_Force_Protection {
<div class="jetpack-protect-warning notice notice-warning is-dismissible" data-dismiss-nonce="<?php echo esc_attr( wp_create_nonce( 'jetpack_protect_multisite_banner_opt_out' ) ); ?>">
<h2><?php esc_html_e( 'Brute Force Protection cannot keep your site secure', 'jetpack-waf' ); ?></h2>
<p><?php esc_html_e( 'Thanks for activating the Brute Force Protection feature! To start protecting your whole WordPress Multisite Network, please network activate the Jetpack plugin. Due to the way logins are handled on WordPress Multisite Networks, Jetpack must be network activated in order for the Brute Force Protection feature to work properly.', 'jetpack-waf' ); ?></p>
<p>
<?php
printf(
/* Translators: placeholder is a plugin name (Jetpack Protect or Jetpack). */
esc_html__( 'Thanks for activating the Brute Force Protection feature! To start protecting your whole WordPress Multisite Network, please network activate the %1$s plugin. Due to the way logins are handled on WordPress Multisite Networks, %1$s must be network activated in order for the Brute Force Protection feature to work properly.', 'jetpack-waf' ),
defined( 'JETPACK_PROTECT_NAME' ) ? esc_html( JETPACK_PROTECT_NAME ) : 'Jetpack'
);
?>
</p>
<p>
<a class="button-primary" href="<?php echo esc_url( network_admin_url( 'plugins.php' ) ); ?>">
@ -823,7 +848,7 @@ class Brute_Force_Protection {
*/
public function kill_login() {
if (
isset( $_GET['action'], $_GET['_wpnonce'] ) &&
isset( $_GET['action'] ) && isset( $_GET['_wpnonce'] ) &&
'logout' === $_GET['action'] &&
wp_verify_nonce( $_GET['_wpnonce'], 'log-out' ) && // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
wp_get_current_user()

View File

@ -33,6 +33,11 @@ class Waf_Compatibility {
/**
* 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
@ -224,5 +229,4 @@ class Waf_Compatibility {
public static function is_brute_force_running_in_jetpack() {
return defined( 'JETPACK__VERSION' ) && version_compare( JETPACK__VERSION, '12', '<' );
}
}

View File

@ -22,6 +22,12 @@ class REST_Controller {
* @return void
*/
public static function register_rest_routes() {
// Ensure routes are only initialized once.
static $routes_registered = false;
if ( $routes_registered ) {
return;
}
register_rest_route(
'jetpack/v4',
'/waf',
@ -51,6 +57,8 @@ class REST_Controller {
'permission_callback' => __CLASS__ . '::waf_permissions_callback',
)
);
$routes_registered = true;
}
/**
@ -137,10 +145,13 @@ class REST_Controller {
}
}
try {
Waf_Runner::update_waf();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
// Only attempt to update the WAF if the module is supported
if ( Waf_Runner::is_supported_environment() ) {
try {
Waf_Runner::update_waf();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
}
}
return self::waf();

View File

@ -7,8 +7,8 @@
namespace Automattic\Jetpack\Waf;
use \WP_CLI;
use \WP_CLI_Command;
use WP_CLI;
use WP_CLI_Command;
/**
* Just a few sample commands to learn how WP-CLI works

View File

@ -30,26 +30,35 @@ class Waf_Initializer {
public static function init() {
// Do not run in unsupported environments
add_action( 'jetpack_get_available_modules', __CLASS__ . '::remove_module_on_unsupported_environments' );
add_action( 'jetpack_get_available_standalone_modules', __CLASS__ . '::remove_standalone_module_on_unsupported_environments' );
// Ensure backwards compatibility
Waf_Compatibility::add_compatibility_hooks();
// Run the WAF on supported environments
if ( Waf_Runner::is_supported_environment() ) {
// Update the WAF after installing or upgrading a relevant Jetpack plugin
add_action( 'upgrader_process_complete', __CLASS__ . '::update_waf_after_plugin_upgrade', 10, 2 );
add_action( 'admin_init', __CLASS__ . '::check_for_waf_update' );
// Register REST routes
add_action( 'rest_api_init', array( new REST_Controller(), 'register_rest_routes' ) );
// Activation/Deactivation hooks
add_action( 'jetpack_activate_module_waf', __CLASS__ . '::on_activation' );
add_action( 'jetpack_deactivate_module_waf', __CLASS__ . '::on_deactivation' );
// Update the WAF after installing or upgrading a relevant Jetpack plugin
add_action( 'upgrader_process_complete', __CLASS__ . '::update_waf_after_plugin_upgrade', 10, 2 );
// Run the WAF
Waf_Runner::initialize();
}
// Check for compatibility updates
add_action( 'admin_init', __CLASS__ . '::check_for_updates' );
// WAF activation/deactivation hooks
add_action( 'jetpack_activate_module_waf', __CLASS__ . '::on_waf_activation' );
add_action( 'jetpack_deactivate_module_waf', __CLASS__ . '::on_waf_deactivation' );
// Brute force protection activation/deactivation hooks
add_action( 'jetpack_activate_module_protect', __CLASS__ . '::on_brute_force_protection_activation' );
add_action( 'jetpack_deactivate_module_protect', __CLASS__ . '::on_brute_force_protection_deactivation' );
// Run brute force protection
Brute_Force_Protection::initialize();
// Run the WAF
if ( Waf_Runner::is_supported_environment() ) {
Waf_Runner::initialize();
}
}
/**
@ -57,7 +66,7 @@ class Waf_Initializer {
*
* @return bool|WP_Error True if the WAF activation is successful, WP_Error otherwise.
*/
public static function on_activation() {
public static function on_waf_activation() {
update_option( Waf_Runner::MODE_OPTION_NAME, 'normal' );
add_option( Waf_Rules_Manager::AUTOMATIC_RULES_ENABLED_OPTION_NAME, false );
@ -68,6 +77,15 @@ class Waf_Initializer {
return $e->get_wp_error();
}
return true;
}
/**
* Activate the Brute force protection on module activation.
*
* @return bool True if the Brute force protection activation is successful
*/
public static function on_brute_force_protection_activation() {
$brute_force_protection = Brute_Force_Protection::instance();
$brute_force_protection->on_activation();
@ -79,13 +97,22 @@ class Waf_Initializer {
*
* @return bool|WP_Error True if the WAF deactivation is successful, WP_Error otherwise.
*/
public static function on_deactivation() {
public static function on_waf_deactivation() {
try {
Waf_Runner::deactivate();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
}
return true;
}
/**
* Deactivate the Brute force protection on module deactivation.
*
* @return bool True if the Brute force protection deactivation is successful.
*/
public static function on_brute_force_protection_deactivation() {
$brute_force_protection = Brute_Force_Protection::instance();
$brute_force_protection->on_deactivation();
@ -138,31 +165,37 @@ class Waf_Initializer {
*
* @return bool|WP_Error True if the WAF is up-to-date or was sucessfully updated, WP_Error if the update failed.
*/
public static function check_for_waf_update() {
public static function check_for_updates() {
if ( get_option( self::NEEDS_UPDATE_OPTION_NAME ) ) {
// Compatiblity patch for cases where an outdated WAF_Constants class has been
// autoloaded by the standalone bootstrap execution at the beginning of the current request.
if ( ! method_exists( Waf_Constants::class, 'define_mode' ) ) {
if ( Waf_Runner::is_supported_environment() ) {
// Compatiblity patch for cases where an outdated WAF_Constants class has been
// autoloaded by the standalone bootstrap execution at the beginning of the current request.
if ( ! method_exists( Waf_Constants::class, 'define_mode' ) ) {
try {
( new Waf_Standalone_Bootstrap() )->generate();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
}
}
Waf_Compatibility::run_compatibility_migrations();
Waf_Constants::define_mode();
if ( ! Waf_Runner::is_allowed_mode( JETPACK_WAF_MODE ) ) {
return new WP_Error( 'waf_mode_invalid', 'Invalid firewall mode.' );
}
try {
Waf_Rules_Manager::generate_ip_rules();
Waf_Rules_Manager::generate_rules();
( new Waf_Standalone_Bootstrap() )->generate();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
}
}
Waf_Compatibility::run_compatibility_migrations();
Waf_Constants::define_mode();
if ( ! Waf_Runner::is_allowed_mode( JETPACK_WAF_MODE ) ) {
return new WP_Error( 'waf_mode_invalid', 'Invalid firewall mode.' );
}
try {
Waf_Rules_Manager::generate_ip_rules();
Waf_Rules_Manager::generate_rules();
( new Waf_Standalone_Bootstrap() )->generate();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
} else {
// If the site doesn't support the request firewall,
// just migrate the IP allow list used by brute force protection.
Waf_Compatibility::migrate_brute_force_protection_ip_allow_list();
}
}
@ -171,7 +204,7 @@ class Waf_Initializer {
}
/**
* Disables the WAF module when on an supported platform.
* Disables the WAF module when on an unsupported platform in Jetpack.
*
* @param array $modules Filterable value for `jetpack_get_available_modules`.
*
@ -185,4 +218,26 @@ class Waf_Initializer {
return $modules;
}
/**
* Disables the WAF module when on an unsupported platform in a standalone plugin.
*
* @param array $modules Filterable value for `jetpack_get_available_standalone_modules`.
*
* @return array Array of module slugs.
*/
public static function remove_standalone_module_on_unsupported_environments( $modules ) {
if ( ! Waf_Runner::is_supported_environment() ) {
// WAF should never be available on unsupported platforms.
$modules = array_filter(
$modules,
function ( $module ) {
return $module !== 'waf';
}
);
}
return $modules;
}
}

View File

@ -202,7 +202,7 @@ class Waf_Request {
$this->url = array( $uri_host, $uri_path, $query_string );
} else {
// otherwise build the URI manually
$uri_scheme = ( ! empty( $_SERVER['HTTPS'] ) && 'on' === $_SERVER['HTTPS'] )
$uri_scheme = ( ! empty( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] )
? 'https'
: 'http';
$uri_host = isset( $_SERVER['HTTP_HOST'] )

View File

@ -97,7 +97,7 @@ class Waf_Runner {
}
// Do not run in the WPCOM context
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
if ( ( new Host() )->is_wpcom_simple() ) {
return false;
}

View File

@ -222,7 +222,7 @@ class Waf_Runtime {
$v['value'] = $this->transforms->$t( $v['value'] );
}
}
unset( $v );
// pass each target value to the operator to find any that match.
$matched = array();
$captures = array();

View File

@ -168,5 +168,4 @@ class Waf_Standalone_Bootstrap {
return $bootstrap_file;
}
}

View File

@ -20,5 +20,4 @@ class File_System_Exception extends Waf_Exception {
* @var string
*/
const SLUG = 'file_system_error';
}

View File

@ -20,5 +20,4 @@ class Rules_API_Exception extends Waf_Exception {
* @var string
*/
const SLUG = 'rules_api_error';
}

View File

@ -32,5 +32,4 @@ class Waf_Exception extends Exception {
public function get_wp_error() {
return new WP_Error( static::SLUG, $this->getMessage() );
}
}