diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 382abf1580..3f3bd2227c 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -78,12 +78,12 @@ def authenticate(self, request): auth_decoded = base64.b64decode(auth[1]).decode('utf-8') except UnicodeDecodeError: auth_decoded = base64.b64decode(auth[1]).decode('latin-1') - auth_parts = auth_decoded.partition(':') - except (TypeError, UnicodeDecodeError, binascii.Error): + + userid, password = auth_decoded.split(':', 1) + except (TypeError, ValueError, UnicodeDecodeError, binascii.Error): msg = _('Invalid basic header. Credentials not correctly base64 encoded.') raise exceptions.AuthenticationFailed(msg) - userid, password = auth_parts[0], auth_parts[2] return self.authenticate_credentials(userid, password, request) def authenticate_credentials(self, userid, password, request=None): diff --git a/tests/authentication/test_authentication.py b/tests/authentication/test_authentication.py index b64c05de84..22e837ef40 100644 --- a/tests/authentication/test_authentication.py +++ b/tests/authentication/test_authentication.py @@ -120,6 +120,22 @@ def test_post_json_passing_basic_auth(self): ) assert response.status_code == status.HTTP_200_OK + def test_post_json_without_password_failing_basic_auth(self): + """Ensure POSTing json without password (even if password is empty string) returns 401""" + self.user.set_password("") + credentials = ('%s' % (self.username)) + base64_credentials = base64.b64encode( + credentials.encode(HTTP_HEADER_ENCODING) + ).decode(HTTP_HEADER_ENCODING) + auth = 'Basic %s' % base64_credentials + response = self.csrf_client.post( + '/basic/', + {'example': 'example'}, + format='json', + HTTP_AUTHORIZATION=auth + ) + assert response.status_code == status.HTTP_401_UNAUTHORIZED + def test_regression_handle_bad_base64_basic_auth_header(self): """Ensure POSTing JSON over basic auth with incorrectly padded Base64 string is handled correctly""" # regression test for issue in 'rest_framework.authentication.BasicAuthentication.authenticate'