Repository: pallets/werkzeug (python)

Issue:
authorization parsing should catch base64 errors
### Steps to reproduce
```
>>> from werkzeug.datastructures import Authorization
>>> Authorization.from_header("Basic foo")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/private/tmp/.venv/lib/python3.11/site-packages/werkzeug/datastructures/auth.py", line 109, in from_header
    username, _, password = base64.b64decode(rest).decode().partition(":")
                            ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/base64.py", line 88, in b64decode
    return binascii.a2b_base64(s, strict_mode=validate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
binascii.Error: Incorrect padding
```

### Expected behavior
I would expect Werkzeug to handle this situation and return `None`.

### Environment
- Python version: `3.11.3`
- Werkzeug version: `2.3.4`


Pull request description:
Fix handling of invalid base64 values
This change will gracefully handle invalid base64 basic authorization values.

- fixes #2717 

Checklist:

- [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
- [ ] Add or update relevant docs, in the docs folder and in code.
- [x] Add an entry in `CHANGES.rst` summarizing the change and linking to the issue.
- [ ] Add `.. versionchanged::` entries in any relevant code docs.
- [x] Run `pre-commit` hooks and fix any issues.
- [x] Run `pytest` and `tox`, no tests failed.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 7c44e1e7..395ae9ad 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,6 +6,7 @@ Version 2.3.5
 Unreleased
 
 -   Python 3.12 compatibility. :issue:`2704`
+-   Fix handling of invalid base64 values in ``Authorization.from_header``. :issue:`2717`
 
 
 Version 2.3.4
diff --git a/src/werkzeug/datastructures/auth.py b/src/werkzeug/datastructures/auth.py
index 709955c4..a88f8a3c 100644
--- a/src/werkzeug/datastructures/auth.py
+++ b/src/werkzeug/datastructures/auth.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 import base64
+import binascii
 import typing as t
 import warnings
 from functools import wraps
@@ -107,7 +108,7 @@ class Authorization:
         if scheme == "basic":
             try:
                 username, _, password = base64.b64decode(rest).decode().partition(":")
-            except UnicodeError:
+            except (binascii.Error, UnicodeError):
                 return None
 
             return cls(scheme, {"username": username, "password": password})


Test patch:
diff --git a/tests/test_http.py b/tests/test_http.py
index 7d76775b..65febf96 100644
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -216,6 +216,9 @@ class TestHTTPUtility:
         assert a.type == "token"
         assert a.token == token
 
+    def test_authorization_basic_incorrect_padding(self):
+        assert Authorization.from_header("Basic foo") is None
+
     def test_bad_authorization_header_encoding(self):
         """If the base64 encoded bytes can't be decoded as UTF-8"""
         content = base64.b64encode(b"\xffser:pass").decode()