python / python/cpython

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

Abierto
#100,612 0 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

topic-email type-bug type-security
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza en la ruta de email.mime.multipart MIMEMultipart.add_header() y reproduce la PoC proporcionada con un filename que contenga CRLF. Rastrea cómo se serializa el filename en la cabecera Content-Disposition y, después, añade cobertura de regresión para el comportamiento indicado; se considera terminado cuando un CRLF diseñado no puede crear líneas de cabecera adicionales y el comportamiento MIME existente permanece intacto.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
security
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.