{"id":"PYSEC-2026-2468","summary":"eml_parser has recursion DoS via nested message/rfc822 attachments","details":"### Summary\n\n`EmlParser.get_raw_body_text()` recurses unconditionally for every nested `message/rfc822` attachment without any depth limit. An attacker who can supply a badly crafted EML file with approximately 120 nested `message/rfc822` parts triggers an unhandled `RecursionError` and aborts parsing of the message. A 12 KB EML file is enough to crash a worker.\nThough this causes the parser to crash, it is an unlikely scenario as the suggested EML that crashes the parser would not pass basic RFC compliance tests.\n\n### Details\n\nThe vulnerable function is `EmlParser.get_raw_body_text()` in `eml_parser/parser.py`. For every part of type `multipart/*`, the function iterates over its sub-parts; for every sub-part of type `message/rfc822`, it calls itself recursively on the inner message:\n\nThere is no depth parameter and no early-abort. CPython's default `sys.recursionlimit` is 1000. Each level of `message/rfc822` nesting adds approximately 8 frames to the stack (parser code + stdlib `_header_value_parser` calls), so roughly 120 nested levels exhaust the limit.\n\nThe `RecursionError` is not caught anywhere along the call chain, so it propagates out of `decode_email_bytes()` and aborts processing of the entire message.\n\n\n### PoC\n\nEnvironment: Python 3.12.3, eml_parser 3.0.0 (`pip install eml_parser==3.0.0`), default `sys.recursionlimit=1000`, Ubuntu 24.04 aarch64. No special configuration of `EmlParser`, default constructor.\n\nSelf-contained reproducer that builds the PoC and triggers the crash:\n\n```python\nimport eml_parser\n\ndef build_poc(depth=124):\n    inner = b\"From: a@a\\r\\nTo: b@b\\r\\nContent-Type: text/plain\\r\\n\\r\\n.\\r\\n\"\n    msg = inner\n    for i in range(depth):\n        b = f\"B{i}\".encode()\n        msg = (\n            b'Content-Type: multipart/mixed; boundary=\"' + b + b'\"\\r\\n\\r\\n'\n            b'--' + b + b'\\r\\nContent-Type: message/rfc822\\r\\n\\r\\n'\n        ) + msg + b'\\r\\n--' + b + b'--\\r\\n'\n    return msg\n\nep = eml_parser.EmlParser()\nep.decode_email_bytes(build_poc())\n# RecursionError after ~76 ms on Apple Silicon (Ubuntu 24.04 aarch64).\n```\n\nNote that the suggested code does not produce an RFC compliant message.\nResulting EML payload size: 12,369 bytes.\nSHA-256 of generated PoC: `00f15f635e21b4144967c2893b37425e6a6bd7b4185c557e5c7e904e1e6d18e8`\n\nThe crash is deterministic on a stock install. No network, no special headers, no large attachments.\n\n### Impact\n\nDenial of service of any pipeline that processes attacker-supplied EML files using `eml_parser`.\n\nA single 12 KB email is enough to crash a worker. If the worker is a long-running process triaging multiple emails, the unhandled exception aborts processing of the whole batch unless the caller wraps the call in a broad `try/except`. Even then, attacker-supplied volume can keep workers in a perpetual restart loop.\n\nThe vulnerability is exploitable pre-authentication in any deployment that ingests emails from external senders which have not been subject to any kind of basic validation.\nConsidering that email messages pass through a mail-server which does some kind of validation, messages as produced by the  *build_poc* function would not reach eml_parser.\nNonetheless recursion depth checks have been implemented to handle the described issue.\n\n\n### Reporter\n\nSebastián Alba Vives (`@Sebasteuo`)\nIndependent security researcher, Senior AppSec Consultant\nLinkedIn: https://www.linkedin.com/in/sebastian-alba\nEmail: sebasjosue84@gmail.com\nPGP: `0D1A E4C2 CFC8 894F 19EA  DA24 45CD CA33 2CF8 31F4`","aliases":["CVE-2026-44844","GHSA-g47v-rwmh-r9f8"],"modified":"2026-07-13T16:31:45.571578729Z","published":"2026-07-13T15:15:43.202977Z","references":[{"type":"WEB","url":"https://github.com/GOVCERT-LU/eml_parser/security/advisories/GHSA-g47v-rwmh-r9f8"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44844"},{"type":"PACKAGE","url":"https://github.com/GOVCERT-LU/eml_parser"},{"type":"PACKAGE","url":"https://pypi.org/project/eml-parser"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-g47v-rwmh-r9f8"}],"affected":[{"package":{"name":"eml-parser","ecosystem":"PyPI","purl":"pkg:pypi/eml-parser"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.0.1"}]}],"versions":["0.9","1.0","1.1","1.10","1.11","1.11.1","1.11.2","1.11.4","1.11.5","1.11.6","1.11.7","1.12.0","1.13.0","1.14.0","1.14.1","1.14.2","1.14.3","1.14.4","1.14.5","1.14.6","1.14.7","1.14.8","1.15.0","1.16.0","1.17.0","1.17.1","1.17.2","1.17.3","1.17.4","1.17.5","1.3","1.4","1.5","1.6","1.7","1.8","1.9","2.0.0","2.0.1","3.0.0"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/eml-parser/PYSEC-2026-2468.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"}]}