diff --git a/.changeset/hash-equals-secret-comparison.md b/.changeset/hash-equals-secret-comparison.md new file mode 100644 index 000000000..36a3702a8 --- /dev/null +++ b/.changeset/hash-equals-secret-comparison.md @@ -0,0 +1,5 @@ +--- +"@faustwp/wordpress-plugin": patch +--- + +fix[faustwp]: use hash_equals() for constant-time secret key comparison in REST and GraphQL permission callbacks diff --git a/plugins/faustwp/includes/graphql/callbacks.php b/plugins/faustwp/includes/graphql/callbacks.php index 7c0cf1fdc..be3a4956e 100644 --- a/plugins/faustwp/includes/graphql/callbacks.php +++ b/plugins/faustwp/includes/graphql/callbacks.php @@ -66,8 +66,9 @@ function filter_introspection( $value, $default_value, $option_name, $section_fi return $value; } - $secret_key = get_secret_key(); - if ( $secret_key !== $_SERVER['HTTP_X_FAUST_SECRET'] ) { + $secret_key = get_secret_key(); + $faust_secret = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FAUST_SECRET'] ) ); + if ( ! hash_equals( $secret_key, $faust_secret ) ) { return $value; } diff --git a/plugins/faustwp/includes/rest/callbacks.php b/plugins/faustwp/includes/rest/callbacks.php index 7574c025a..fa600ea97 100644 --- a/plugins/faustwp/includes/rest/callbacks.php +++ b/plugins/faustwp/includes/rest/callbacks.php @@ -419,7 +419,7 @@ function rest_authorize_permission_callback( \WP_REST_Request $request ) { $header_key = $request->get_header( 'x-faustwp-secret' ); if ( $secret_key && $header_key ) { - return $secret_key === $header_key; + return hash_equals( $secret_key, $header_key ); } return false; @@ -444,7 +444,7 @@ function wpac_authorize_permission_callback( \WP_REST_Request $request ) { $header_key = $request->get_header( 'x-wpe-headless-secret' ); if ( $secret_key && $header_key ) { - return $secret_key === $header_key; + return hash_equals( $secret_key, $header_key ); } return false;