decode base64 credentials as utf8; adjust tests (#7193)

* decode base64 credentials as utf8; adjust tests

* basicauth: add dedicated test for utf8 credentials

* basicauth: add fallback to latin-1 encoding if utf-8 fails
This commit is contained in:
Kevin Kennell 2020-02-17 17:10:52 +01:00 committed by GitHub
parent f81ca78642
commit d7b218f5eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -74,7 +74,11 @@ class BasicAuthentication(BaseAuthentication):
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)
try: try:
auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':') try:
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): except (TypeError, UnicodeDecodeError, binascii.Error):
msg = _('Invalid basic header. Credentials not correctly base64 encoded.') msg = _('Invalid basic header. Credentials not correctly base64 encoded.')
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)

View File

@ -159,6 +159,25 @@ class BasicAuthTests(TestCase):
) )
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
def test_decoding_of_utf8_credentials(self):
username = 'walterwhité'
email = 'walterwhite@example.com'
password = 'pässwörd'
User.objects.create_user(
username, email, password
)
credentials = ('%s:%s' % (username, password))
base64_credentials = base64.b64encode(
credentials.encode('utf-8')
).decode(HTTP_HEADER_ENCODING)
auth = 'Basic %s' % base64_credentials
response = self.csrf_client.post(
'/basic/',
{'example': 'example'},
HTTP_AUTHORIZATION=auth
)
assert response.status_code == status.HTTP_200_OK
@override_settings(ROOT_URLCONF=__name__) @override_settings(ROOT_URLCONF=__name__)
class SessionAuthTests(TestCase): class SessionAuthTests(TestCase):