Skip to content

Commit

Permalink
WWWAuthenticate.from_header handles base64 padding in token
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed May 1, 2023
1 parent 6e63efe commit 2051469
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Version 2.3.4

Unreleased

- ``Authorization.from_header`` detects tokens that end with base64 padding (``=``).
:issue:`2685`
- ``Authorization.from_header`` and ``WWWAuthenticate.from_header`` detects tokens
that end with base64 padding (``=``). :issue:`2685`


Version 2.3.3
Expand Down
9 changes: 5 additions & 4 deletions src/werkzeug/datastructures/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,13 @@ def from_header(cls, value: str | None) -> te.Self | None:
scheme, _, rest = value.partition(" ")
scheme = scheme.lower()
rest = rest.strip()
parameters = parse_dict_header(rest)

if len(parameters) == 1 and parameters[next(iter(parameters))] is None:
return cls(scheme, None, rest)
if "=" in rest.rstrip("="):
# = that is not trailing, this is parameters.
return cls(scheme, parse_dict_header(rest), None)

return cls(scheme, parameters, None)
# No = or only trailing =, this is a token.
return cls(scheme, None, rest)

def to_header(self) -> str:
"""Produce a ``WWW-Authenticate`` header value representing this data."""
Expand Down
13 changes: 13 additions & 0 deletions tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,19 @@ def test_www_authenticate_header(self):
assert WWWAuthenticate.from_header("broken").type == "broken"
assert WWWAuthenticate.from_header("") is None

def test_www_authenticate_token_padding(self):
# padded with =
token = base64.b64encode(b"This has base64 padding").decode()
a = WWWAuthenticate.from_header(f"Token {token}")
assert a.type == "token"
assert a.token == token

# padded with ==
token = base64.b64encode(b"This has base64 padding..").decode()
a = WWWAuthenticate.from_header(f"Token {token}")
assert a.type == "token"
assert a.token == token

def test_www_authenticate_eq(self):
basic1 = WWWAuthenticate.from_header("Basic realm=abc")
basic2 = WWWAuthenticate("basic", {"realm": "abc"})
Expand Down

0 comments on commit 2051469

Please sign in to comment.