Title: Excess data in not handled properly in binascii.a2b_base64()
Type: security Stage: patch review
Components: Library (Lib) Versions: Python 3.10
Status: open Resolution:
Dependencies: Superseder:
Assigned To: gregory.p.smith Nosy List: eric.smith, gregory.p.smith, idan22moral, python-dev
Priority: normal Keywords: patch

Created on 2021-01-31 18:11 by idan22moral, last changed 2021-03-13 09:45 by gregory.p.smith.

Pull Requests
URL Status Linked Edit
PR 24402 open python-dev, 2021-01-31 18:18
Messages (1)
msg386032 - (view) Author: Idan Moral (idan22moral) * Date: 2021-01-31 18:11
Currently, when providing binascii.a2b_base64() base-64 input with excess data after the padding ('='/'=='), the excess data is ignored.


import binascii
binascii.a2b_base64(b'aGVsbG8=')       # b'hello' (valid)
binascii.a2b_base64(b'aGVsbG8==')      # b'hello' (ignoring data)
binascii.a2b_base64(b'aGVsbG8=python') # b'hello' (ignoring data)

Note: MANY libraries (such as the all-time favorite `base64`) use this function as their decoder.

Why is it problematic:
* User input can contain additional data after base64 data, which can lead to unintended behavior in products.
* Well-crafted user input can be used to bypass conditions in code (example in the referenced tweet).
* Can be used to target vulnerable libraries and bypass authentication mechanism such as JWT (potentially).

The logic behind my fix PR on GitHub:
* Before deciding to finish the function (after knowing the fact that we passed the data padding),
  we should check if there's no more data after the padding.
* If excess data exists, we should raise an error, free the allocated writer, and return null.
* Else, everything's fine, and we can proceed to the function's end as previously.

Though not publicly disclosed, this behavior can lead to security issues in heavily-used projects.
Preventing this behavior sounds more beneficial than harmful, since there's no known good usage for this behavior.

From what I read, the python implementation in not so close (when speaking about this case of course) to the base64 RFC.

Thanks to Ori Damari (twitter: for bringing this behavior up,
and thanks to Ryan Mast (twitter:, and many of the other great guys for discussing the problem in the comments.

Link to the tweet:


Idan Moral
Date User Action Args
2021-03-13 09:45:31gregory.p.smithsetassignee: gregory.p.smith

nosy: + gregory.p.smith
2021-01-31 18:29:23eric.smithsetnosy: + eric.smith
2021-01-31 18:18:49python-devsetkeywords: + patch
nosy: + python-dev

pull_requests: + pull_request23216
stage: patch review
2021-01-31 18:11:52idan22moralcreate