python / python/cpython

Email's as_bytes() method unfolds a protected header in a pgp signed message part breaking the signature.

Aperta
#153,822 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

stdlib topic-email type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug report

Bug description:
>>> from email import parser, policy
>>> # Create a bytes parser with default policy
>>> parser = parser.BytesParser(policy=policy.default)
>>> # Set bytes to the raw message content. Note the In-Reply-To header is folded in both the outer message
>>> # and in the proctected headers in the signed text/plain part.
>>> bytes = b"""In-Reply-To:
...  <CAMFngpXc_66qL0nUkHtT5g98BhWHPE8-KFtc6=87OvA-U7O9cw@mail.gmail.com>
... MIME-Version: 1.0
... Content-Type: multipart/signed; boundary="nextPartVzbFsyfPQFC9aKXYcHllLg";
...  micalg="pgp-sha512"; protocol="application/pgp-signature"
... 
... --nextPartVzbFsyfPQFC9aKXYcHllLg
... Content-Transfer-Encoding: 7Bit
... Content-Type: text/plain; charset="utf-8"; protected-headers="v1"
... In-Reply-To:
...  <CAMFngpXc_66qL0nUkHtT5g98BhWHPE8-KFtc6=87OvA-U7O9cw@mail.gmail.com>
... MIME-Version: 1.0
... 
... fake message here
... --nextPartVzbFsyfPQFC9aKXYcHllLg
... Content-Type: application/pgp-signature; name="signature.asc"
... Content-Description: This is a digitally signed message part.
... Content-Transfer-Encoding: 7Bit
... 
... -----BEGIN PGP SIGNATURE-----
... 
... iJEEABYKADkWIQRIePpI7xqJT+Ra2G9Prbu26Vsl/AUCalfydhsUgAAAAAAEAA5t
... YW51MiwyLjUrMS4xMiwyLDIACgkQT627tulbJfzupAD/a1gphNvf7nc+sYph/EJi
... W61+Kg356YYzRXS7SsfFI14A/2z4u28/Chqd/ETNh4VRYfl4Rf8N7eDMpFOZSEdM
... bTkF
... =QWJd
... -----END PGP SIGNATURE-----
... 
... --nextPartVzbFsyfPQFC9aKXYcHllLg--
... """
>>> # Create a message object.
>>> msg = parser.parsebytes(bytes)
>>> # and print its as_bytes() representation.
>>> print(msg.as_bytes().decode())
In-Reply-To:
 <CAMFngpXc_66qL0nUkHtT5g98BhWHPE8-KFtc6=87OvA-U7O9cw@mail.gmail.com>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="nextPartVzbFsyfPQFC9aKXYcHllLg";
 micalg="pgp-sha512"; protocol="application/pgp-signature"

--nextPartVzbFsyfPQFC9aKXYcHllLg
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="utf-8"; protected-headers="v1"
In-Reply-To: <CAMFngpXc_66qL0nUkHtT5g98BhWHPE8-KFtc6=87OvA-U7O9cw@mail.gmail.com>
MIME-Version: 1.0

fake message here
--nextPartVzbFsyfPQFC9aKXYcHllLg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iJEEABYKADkWIQRIePpI7xqJT+Ra2G9Prbu26Vsl/AUCalfydhsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIACgkQT627tulbJfzupAD/a1gphNvf7nc+sYph/EJi
W61+Kg356YYzRXS7SsfFI14A/2z4u28/Chqd/ETNh4VRYfl4Rf8N7eDMpFOZSEdM
bTkF
=QWJd
-----END PGP SIGNATURE-----

--nextPartVzbFsyfPQFC9aKXYcHllLg--

>>> # Note that the protected In-Reply-To header in the signed text/plain part is unfolded even though it is
>>> # 81 bytes long.
>>> # Now get only the text/plain part.
>>> part = msg.get_payload(0)
>>> # And see it as_bytes().
>>> print(part.as_bytes().decode())
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="utf-8"; protected-headers="v1"
In-Reply-To:
 <CAMFngpXc_66qL0nUkHtT5g98BhWHPE8-KFtc6=87OvA-U7O9cw@mail.gmail.com>
MIME-Version: 1.0

fake message here
>>> # And here the header is properly folded.

The problem here is if a message of which the above is an excerpt is received by some application, e.g. Mailman, and later resent to recipients by passing the message object to Python's smtplib.SMTP.send_message() method which serializes the message with the as_bytes() method applied to the whole message, the resent message has the unfolded protected In-Reply-To header in the signed part breaking the signature.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs
  • gh-154107

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Iniziare con la riproduzione di BytesParser e Message.as_bytes() nel report, quindi seguire la serializzazione tramite smtplib.SMTP.send_message(). Verificare che l’header In-Reply-To protetto rimanga ripiegato quando il messaggio multipart/signed viene serializzato, in modo che la firma originale non venga invalidata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
backend
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.