From 3ecc833246fcbda9a5b42c4c047a6b52fcf93d30 Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Tue, 27 Feb 2024 10:00:50 -0500 Subject: [PATCH 1/6] Bump to 1.3.0 --- CHANGELOG.md | 3 ++- README.md | 2 +- plugin.php | 26 ++++++++++++++++++++------ readme.txt | 2 +- settings.php | 16 ++++++++++++++++ tests/RestApiGuardTest.php | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a4303b..c53642c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ All notable changes to `wp-rest-guard` will be documented in this file. -## v1.2.1 - 2024-02-26 +## v1.3.0 - 2024-02-27 - Allow the claims to be added to added to a generated JWT via filter. +- Don't check `OPTIONS` requests by default. ## v1.2.0 - 2024-02-22 diff --git a/README.md b/README.md index 573f177..2cb4864 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # REST API Guard -Stable tag: 1.2.1 +Stable tag: 1.3.0 Requires at least: 6.0 diff --git a/plugin.php b/plugin.php index 37d1098..e6ab2b7 100644 --- a/plugin.php +++ b/plugin.php @@ -3,9 +3,9 @@ * Plugin Name: REST API Guard * Plugin URI: https://github.com/alleyinteractive/wp-rest-api-guard * Description: Restrict and control access to the REST API - * Version: 1.2.0 + * Version: 1.3.0 * Author: Sean Fisher - * Author URI: https://alley.co/ + * Author URI: https://alley.com/ * Requires at least: 6.0 * Tested up to: 6.3 * @@ -59,6 +59,18 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques $settings = []; } + /** + * Allow OPTIONS requests to bypass the REST API Guard checks by default. + * + * This is useful for CORS preflight requests. + * + * @param bool $allow Whether to allow OPTIONS requests, default true. + * @param \WP_REST_Request $request REST API Request. + */ + if ( 'OPTIONS' === $request->get_method() && ! apply_filters( 'rest_api_guard_check_options_requests', $settings['check_options_requests'] ?? false, $request ) ) { + return false; + } + if ( class_exists( JWT::class ) ) { /** * Check if the anonymous request requires a JSON Web Token (JWT). @@ -149,9 +161,10 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques /** * Prevent access to the root of the REST API. * - * @param bool $prevent Whether to prevent anonymous access, default false. + * @param bool $prevent Whether to prevent anonymous access, default false. + * @param string $endpoint The endpoint of the request. */ - if ( '/' === $endpoint && false === apply_filters( 'rest_api_guard_allow_index_access', $settings['allow_index_access'] ?? false ) ) { + if ( '/' === $endpoint && false === apply_filters( 'rest_api_guard_allow_index_access', $settings['allow_index_access'] ?? false, $endpoint ) ) { return true; } @@ -171,9 +184,10 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques /** * Prevent access to the /wp/v2/users endpoints by default. * - * @param bool $pre Whether to prevent access to the /wp/v2/users endpoints. + * @param bool $pre Whether to prevent access to the /wp/v2/users endpoints. + * @param string $endpoint The endpoint of the request. */ - if ( preg_match( '#^/wp/v\d+/users($|/)#', $endpoint ) && false === apply_filters( 'rest_api_guard_allow_user_access', $settings['allow_user_access'] ?? false ) ) { + if ( preg_match( '#^/wp/v\d+/users($|/)#', $endpoint ) && false === apply_filters( 'rest_api_guard_allow_user_access', $settings['allow_user_access'] ?? false, $endpoint ) ) { return true; } diff --git a/readme.txt b/readme.txt index 0f8f867..c5c4f3d 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ === REST API Guard === -Stable tag: 1.2.1 +Stable tag: 1.3.0 Requires at least: 6.0 Tested up to: 6.3 Requires PHP: 8.0 diff --git a/settings.php b/settings.php index 0279dca..dba3528 100644 --- a/settings.php +++ b/settings.php @@ -145,6 +145,21 @@ function on_admin_init() { ], ); + add_settings_field( + 'check_options_requests', + __( 'Apply checks to OPTIONS requests', 'rest-api-guard' ), + __NAMESPACE__ . '\render_field', + SETTINGS_KEY, + SETTINGS_KEY, + [ + 'description' => __( 'Apply the same checks to OPTIONS requests as other requests.', 'rest-api-guard' ), + 'additional' => __( 'By default, the plugin will not apply any checks to OPTIONS requests. This setting will force the plugin to apply the same checks to OPTIONS requests as other requests. For CORS requests, this may need to be disabled to allow authentication with a JWT.', 'rest-api-guard' ), + 'filter' => 'rest_api_guard_check_options_requests', + 'id' => 'check_options_requests', + 'type' => 'checkbox', + ], + ); + add_settings_field( 'anonymous_requests_allowlist', __( 'Anonymous Request Allowlist', 'rest-api-guard' ), @@ -232,6 +247,7 @@ function sanitize_settings( $input ) { 'allow_index_access' => ! empty( $input['allow_index_access'] ), 'allow_namespace_access' => ! empty( $input['allow_namespace_access'] ), 'allow_user_access' => ! empty( $input['allow_user_access'] ), + 'check_options_requests' => ! empty( $input['check_options_requests'] ), 'anonymous_requests_allowlist' => ! empty( $input['anonymous_requests_allowlist'] ) ? sanitize_textarea_field( $input['anonymous_requests_allowlist'] ) : '', 'anonymous_requests_denylist' => ! empty( $input['anonymous_requests_denylist'] ) ? sanitize_textarea_field( $input['anonymous_requests_denylist'] ) : '', 'authentication_jwt' => ! empty( $input['authentication_jwt'] ), diff --git a/tests/RestApiGuardTest.php b/tests/RestApiGuardTest.php index 2d87c2d..6bd3463 100644 --- a/tests/RestApiGuardTest.php +++ b/tests/RestApiGuardTest.php @@ -121,6 +121,42 @@ public function test_prevent_anonymous_access_settings() { $this->get( rest_url( '/wp/v2/tags' ) )->assertUnauthorized(); } + public function test_check_options_requests() { + $this->expectApplied( 'rest_api_guard_check_options_requests' )->times( 3 ); + + // Check the default settings. + update_option( + SETTINGS_KEY, + [ + 'prevent_anonymous_access' => true, + ] + ); + + $this->options( rest_url( '/wp/v2/categories' ) )->assertOk(); + $this->get( rest_url( '/wp/v2/categories' ) )->assertUnauthorized(); + + update_option( + SETTINGS_KEY, + [ + 'prevent_anonymous_access' => true, + 'check_options_requests' => true, + ] + ); + + $this->options( rest_url( '/wp/v2/categories' ) )->assertUnauthorized(); + + update_option( + SETTINGS_KEY, + [ + 'prevent_anonymous_access' => true, + ] + ); + + add_filter( 'rest_api_guard_check_options_requests', fn () => true ); + + $this->options( rest_url( '/wp/v2/categories' ) )->assertUnauthorized(); + } + public function test_prevent_access_allowlist_code() { $this->get( rest_url( '/wp/v2/categories' ) )->assertOk(); From 0f78b8b36ae98c781f7de55b74303d816dff79c6 Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Wed, 28 Feb 2024 14:25:23 -0500 Subject: [PATCH 2/6] Update CHANGELOG.md Co-authored-by: David Herrera --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c53642c..5b0e329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to `wp-rest-guard` will be documented in this file. ## v1.3.0 - 2024-02-27 -- Allow the claims to be added to added to a generated JWT via filter. +- Allow the claims to be added to a generated JWT via filter. - Don't check `OPTIONS` requests by default. ## v1.2.0 - 2024-02-22 From 7ad3aa020322cc196de0cb25092f4dfe410f2ebb Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Wed, 28 Feb 2024 14:25:29 -0500 Subject: [PATCH 3/6] Update plugin.php Co-authored-by: David Herrera --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index e6ab2b7..00a9de6 100644 --- a/plugin.php +++ b/plugin.php @@ -64,7 +64,7 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques * * This is useful for CORS preflight requests. * - * @param bool $allow Whether to allow OPTIONS requests, default true. + * @param bool $check Whether to check OPTIONS requests. Default false. * @param \WP_REST_Request $request REST API Request. */ if ( 'OPTIONS' === $request->get_method() && ! apply_filters( 'rest_api_guard_check_options_requests', $settings['check_options_requests'] ?? false, $request ) ) { From 8adc393b262cf049f0e12c436543da77d3c54ddf Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Wed, 28 Feb 2024 14:25:33 -0500 Subject: [PATCH 4/6] Update plugin.php Co-authored-by: David Herrera --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index 00a9de6..b1469b3 100644 --- a/plugin.php +++ b/plugin.php @@ -184,7 +184,7 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques /** * Prevent access to the /wp/v2/users endpoints by default. * - * @param bool $pre Whether to prevent access to the /wp/v2/users endpoints. + * @param bool $pre Whether to allow access to the /wp/v2/users endpoints. * @param string $endpoint The endpoint of the request. */ if ( preg_match( '#^/wp/v\d+/users($|/)#', $endpoint ) && false === apply_filters( 'rest_api_guard_allow_user_access', $settings['allow_user_access'] ?? false, $endpoint ) ) { From 8ae6405657bbefcc57b75bec0d62d85c26d53013 Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Wed, 28 Feb 2024 14:25:42 -0500 Subject: [PATCH 5/6] Update plugin.php Co-authored-by: David Herrera --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index b1469b3..442b0a2 100644 --- a/plugin.php +++ b/plugin.php @@ -161,7 +161,7 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques /** * Prevent access to the root of the REST API. * - * @param bool $prevent Whether to prevent anonymous access, default false. + * @param bool $prevent Whether to allow anonymous access to the REST API index. Default false. * @param string $endpoint The endpoint of the request. */ if ( '/' === $endpoint && false === apply_filters( 'rest_api_guard_allow_index_access', $settings['allow_index_access'] ?? false, $endpoint ) ) { From e9051f2c6c208a0aa06573337926a68f769af15a Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Wed, 28 Feb 2024 14:25:48 -0500 Subject: [PATCH 6/6] Update plugin.php Co-authored-by: David Herrera --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index 442b0a2..2392563 100644 --- a/plugin.php +++ b/plugin.php @@ -60,7 +60,7 @@ function should_prevent_anonymous_access( WP_REST_Server $server, WP_REST_Reques } /** - * Allow OPTIONS requests to bypass the REST API Guard checks by default. + * Filters whether the REST API Guard should check OPTIONS requests. * * This is useful for CORS preflight requests. *