python / python/cpython

CRLF Injection vulnerability in "email.mime.multipart" > "MIMEMultipart" > "add_header()"

Aperta
#100,612 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

Summary

I found CRLF Injection ( File Content Injection / (Potential) Tampering file extension ) Vulnerability in email.mime.multipart > class MIMEMultipart > add_header().

This problem is caused by the lack of escaping of "filename" in Multipart > Mail.
Normally, the following three characters are escaped

  • \r --> \\r
  • \n --> \\n
  • " --> \"
    However, the method in question does not escape \r\n
    ( " (double-quote) is escaped. " --> \" )

Therefore, if a crafted file name is inserted, CRLF Injection will occur in the Content-Disposition header of multipart body.

My calculated CVSS:
Score: 3.1 (Low)
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:N


PoC:

OS: macOS Monterey (v12.6.1)
Python ver: v3.10.3
PoC Code:
(please edit filepath)

from email.mime.application import MIMEApplication
def main():
  filepath = "/Users/XXXXXXXXXX/Desktop/example.txt"
  # If \r\n (CRLF) is present, the file will fail to load (on mac OS).
  with open(filepath, "rb") as f:
    mb = MIMEApplication(f.read())
  disposition_filename = "malicious_test.sh\r\n.txt"
  # If \r\n (CRLF) is present, the contents of the file can be Injected.
  mb.add_header("Content-Disposition", "attachment", filename=disposition_filename)
  print(mb)
if __name__ == '__main__':
  main()

Output:

Content-Type: application/octet-stream
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="malicious_test.sh
.txt"
IyEvYmluL2Jhc2gKCmVjaG8gImhlbGxvIg==

Injected Line:

Content-Disposition: attachment; filename="malicious_test.sh
.txt"


Affect

This problem is very limited.
The reason for this is that if [ \r, \n ] are included when a file is opened, an Exception will be thrown.

with open(filepath, "rb") as f:

However, it is not always safe to do so, since the file name may be given by an external parameter, DB, etc.
In addition, data can be added to the header content within Multipart, allowing for a variety of attacks.

It may be possible to insert multiple Content-Dispositions, falsify the filename, or inject malicious shell code after making the file .sh .


Reference:

As far as I can tell, the following service systems escape [ \r \n " ] to [ \\r \\n \" ]


The Python PSRT team has agreed to published this information.

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

Parti dal percorso email.mime.multipart MIMEMultipart.add_header() e riproduci la PoC fornita con un filename contenente CRLF. Traccia come il filename viene serializzato nell’header Content-Disposition, quindi aggiungi una copertura di regressione per il comportamento segnalato; il lavoro è completato quando un CRLF appositamente costruito non può creare righe di header aggiuntive e il comportamento MIME esistente rimane intatto.

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

Valutazione

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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.