Skip to content

Commit

Permalink
REST API: Correct parsing of password from Authorization header when …
Browse files Browse the repository at this point in the history
…processing Application Password credentials.

Exit early when parsing Application Password credentials if Authorization header value does not contain at least one colon. The `Authorization` Basic header must use a colon to separate the username and password components per RFC 7617, so a username-only string is malformed and should not be processed.

Split `Authorization` header only on the first colon, properly handling passwords containing colons.

Resolves PHP 8.0 warning when `list()` was called on an exploded credentials array containing only one element.

Props kalpeshh, shooper, sc0ttkclark, jrf, mukesh27, oglekler, nicolefurlan.
Fixes #57512.



git-svn-id: https://develop.svn.wordpress.org/trunk@56804 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
kadamwhite committed Oct 9, 2023
1 parent 4c059cc commit a55dcf4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/wp-includes/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ function wp_populate_basic_auth_from_authorization_header() {
$token = substr( $header, 6 );
$userpass = base64_decode( $token );

list( $user, $pass ) = explode( ':', $userpass );
// There must be at least one colon in the string.
if ( ! str_contains( $userpass, ':' ) ) {
return;
}

list( $user, $pass ) = explode( ':', $userpass, 2 );

// Now shove them in the proper keys where we're expecting later on.
$_SERVER['PHP_AUTH_USER'] = $user;
Expand Down
42 changes: 42 additions & 0 deletions tests/phpunit/tests/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -844,4 +844,46 @@ public function data_application_passwords_can_use_capability_checks_to_determin
'not allowed' => array( 'subscriber', false ),
);
}

/*
* @ticket 57512
* @covers ::wp_populate_basic_auth_from_authorization_header
*/
public function tests_basic_http_authentication_with_username_and_password() {
// Header passed as "username:password".
$_SERVER['HTTP_AUTHORIZATION'] = 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=';

wp_populate_basic_auth_from_authorization_header();

$this->assertSame( $_SERVER['PHP_AUTH_USER'], 'username' );
$this->assertSame( $_SERVER['PHP_AUTH_PW'], 'password' );
}

/*
* @ticket 57512
* @covers ::wp_populate_basic_auth_from_authorization_header
*/
public function tests_basic_http_authentication_with_username_only() {
// Malformed header passed as "username" with no password.
$_SERVER['HTTP_AUTHORIZATION'] = 'Basic dXNlcm5hbWU=';

wp_populate_basic_auth_from_authorization_header();

$this->assertArrayNotHasKey( 'PHP_AUTH_USER', $_SERVER );
$this->assertArrayNotHasKey( 'PHP_AUTH_PW', $_SERVER );
}

/*
* @ticket 57512
* @covers ::wp_populate_basic_auth_from_authorization_header
*/
public function tests_basic_http_authentication_with_colon_in_password() {
// Header passed as "username:pass:word" where password contains colon.
$_SERVER['HTTP_AUTHORIZATION'] = 'Basic dXNlcm5hbWU6cGFzczp3b3Jk';

wp_populate_basic_auth_from_authorization_header();

$this->assertSame( $_SERVER['PHP_AUTH_USER'], 'username' );
$this->assertSame( $_SERVER['PHP_AUTH_PW'], 'pass:word' );
}
}

0 comments on commit a55dcf4

Please sign in to comment.