Skip to content

Commit 5d73ec8

Browse files
fix[faustwp]: (#2310) use hash_equals for secret key comparison (#2312)
Replace timing-vulnerable === comparisons with hash_equals() for the shared secret key in rest_authorize_permission_callback(), wpac_authorize_permission_callback(), and filter_introspection(). The codebase already uses hash_equals() for HMAC validation in auth/functions.php — these three spots were missed. Also sanitize the $_SERVER['HTTP_X_FAUST_SECRET'] superglobal with wp_unslash() and sanitize_text_field() per WordPress coding standards before passing to hash_equals(). Split out from #2312 per @josephfusco review feedback — the blockset cleanup half moves to a separate PR so each half can be reviewed and reverted independently. Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
1 parent b6eebd5 commit 5d73ec8

3 files changed

Lines changed: 10 additions & 4 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@faustwp/wordpress-plugin": patch
3+
---
4+
5+
fix[faustwp]: use hash_equals() for constant-time secret key comparison in REST and GraphQL permission callbacks

plugins/faustwp/includes/graphql/callbacks.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ function filter_introspection( $value, $default_value, $option_name, $section_fi
6666
return $value;
6767
}
6868

69-
$secret_key = get_secret_key();
70-
if ( $secret_key !== $_SERVER['HTTP_X_FAUST_SECRET'] ) {
69+
$secret_key = get_secret_key();
70+
$faust_secret = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FAUST_SECRET'] ) );
71+
if ( ! hash_equals( $secret_key, $faust_secret ) ) {
7172
return $value;
7273
}
7374

plugins/faustwp/includes/rest/callbacks.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ function rest_authorize_permission_callback( \WP_REST_Request $request ) {
419419
$header_key = $request->get_header( 'x-faustwp-secret' );
420420

421421
if ( $secret_key && $header_key ) {
422-
return $secret_key === $header_key;
422+
return hash_equals( $secret_key, $header_key );
423423
}
424424

425425
return false;
@@ -444,7 +444,7 @@ function wpac_authorize_permission_callback( \WP_REST_Request $request ) {
444444
$header_key = $request->get_header( 'x-wpe-headless-secret' );
445445

446446
if ( $secret_key && $header_key ) {
447-
return $secret_key === $header_key;
447+
return hash_equals( $secret_key, $header_key );
448448
}
449449

450450
return false;

0 commit comments

Comments
 (0)