Skip to content

Commit be6b51f

Browse files
committed
Check signature and nonce during authorization
Thanks to @bradyvercher for responsibly disclosing this issue to the API team.
1 parent 74ead6a commit be6b51f

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

lib/class-wp-rest-oauth1.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,7 @@ public function dispatch( $route ) {
267267
return new WP_Error( 'json_oauth1_missing_parameter', __( 'No OAuth parameters supplied', 'rest_oauth1' ), array( 'status' => 400 ) );
268268
}
269269

270-
return $this->generate_access_token(
271-
$params['oauth_consumer_key'],
272-
$params['oauth_token'],
273-
$params['oauth_verifier']
274-
);
270+
return $this->generate_access_token( $params );
275271

276272
default:
277273
return new WP_Error( 'json_oauth1_invalid_route', __( 'Route is invalid', 'rest_oauth1' ), array( 'status' => 404 ) );
@@ -341,6 +337,11 @@ public function generate_request_token( $params ) {
341337
return $result;
342338
}
343339

340+
$error = $this->check_oauth_timestamp_and_nonce( $consumer, $params['oauth_timestamp'], $params['oauth_nonce'] );
341+
if ( is_wp_error( $error ) ) {
342+
return $error;
343+
}
344+
344345
// Generate token
345346
$key = apply_filters( 'json_oauth1_request_token_key', wp_generate_password( self::TOKEN_KEY_LENGTH, false ) );
346347
$data = array(
@@ -546,23 +547,39 @@ public function get_access_token( $oauth_token ) {
546547
* @param string $oauth_token Request token key
547548
* @return WP_Error|array OAuth token data on success, error otherwise
548549
*/
549-
public function generate_access_token( $oauth_consumer_key, $oauth_token, $oauth_verifier ) {
550-
$token = $this->get_request_token( $oauth_token );
550+
public function generate_access_token( $params ) {
551+
$consumer = WP_REST_OAuth1_Client::get_by_key( $params['oauth_consumer_key'] );
552+
if ( is_wp_error( $consumer ) ) {
553+
return $consumer;
554+
}
555+
556+
$token = $this->get_request_token( $params['oauth_token'] );
551557
if ( is_wp_error( $token ) ) {
552558
return $token;
553559
}
554560

561+
// Check the OAuth request signature against the current request
562+
$result = $this->check_oauth_signature( $consumer, $params, $token );
563+
if ( is_wp_error( $result ) ) {
564+
return $result;
565+
}
566+
567+
$error = $this->check_oauth_timestamp_and_nonce( $consumer, $params['oauth_timestamp'], $params['oauth_nonce'] );
568+
if ( is_wp_error( $error ) ) {
569+
return $error;
570+
}
571+
555572
// Check verification
556573
if ( $token['authorized'] !== true ) {
557574
return new WP_Error( 'json_oauth1_unauthorized_token', __( 'OAuth token has not been authorized', 'rest_oauth1' ), array( 'status' => 401 ) );
558575
}
559576

560-
if ( $oauth_verifier !== $token['verifier'] ) {
577+
if ( ! hash_equals( (string) $params['oauth_verifier'], (string) $token['verifier'] ) ) {
561578
return new WP_Error( 'json_oauth1_invalid_verifier', __( 'OAuth verifier does not match', 'rest_oauth1' ), array( 'status' => 400 ) );
562579
}
563580

564581
$this->should_attempt = false;
565-
$consumer = WP_REST_OAuth1_Client::get_by_key( $oauth_consumer_key );
582+
$consumer = WP_REST_OAuth1_Client::get_by_key( $params['oauth_consumer_key'] );
566583
$this->should_attempt = true;
567584

568585
if ( is_wp_error( $consumer ) ) {
@@ -581,7 +598,7 @@ public function generate_access_token( $oauth_consumer_key, $oauth_token, $oauth
581598
add_option( 'oauth1_access_' . $key, $data, null, 'no' );
582599

583600
// Delete the request token
584-
$this->remove_request_token( $oauth_token );
601+
$this->remove_request_token( $params['oauth_token'] );
585602

586603
// Return the new token's data
587604
$data = array(

0 commit comments

Comments
 (0)