Skip to content

Security: Uncontrolled Recursion DoS in parser.py (CWE-674) #459

Closed

Description

@spartan8806

Security Vulnerability: Uncontrolled Recursion DoS

CWE: CWE-674: Uncontrolled Recursion
Severity: MEDIUM (CVSS 5.3 — AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L)
90-day disclosure deadline: 2026-06-06

Summary

The recursive call chains in tomlkit/parser.py have no depth limit. A crafted TOML input with deeply nested arrays or inline tables triggers a RecursionError, crashing the Python process.

Affected Code

  • File: tomlkit/parser.py
  • Lines: 434-435, 589, 621-650
  • Call chains:
    • _parse_value → _parse_array → _parse_value (nested arrays)
    • _parse_value → _parse_inline_table → _parse_key_value → _parse_value (nested inline tables)

Proof of Concept

import tomlkit

# Deeply nested arrays — crashes with RecursionError
payload = 'x = ' + '[' * 500 + '1' + ']' * 500
tomlkit.parse(payload)  # RecursionError

# Deeply nested inline tables
payload2 = 'x = ' + '{a = ' * 200 + '1' + '}' * 200
tomlkit.parse(payload2)  # RecursionError

Impact

Denial of service against any application that parses user-supplied TOML using tomlkit. This includes:

  • Web services accepting TOML configuration via API
  • CI/CD systems parsing pyproject.toml from untrusted sources
  • Any service where users can upload or submit TOML content

The RecursionError kills the current thread/request handler. Depending on the server architecture, this could crash the entire process.

Suggested Fix

Add a recursion depth counter with a configurable maximum (e.g., 100). When the limit is exceeded, raise tomlkit.exceptions.ParseError instead of allowing the unbounded recursion. Example approach:

# In Parser.__init__:
self._recursion_depth = 0
self._max_recursion_depth = max_recursion_depth  # default 100

# In _parse_value, _parse_array, _parse_inline_table:
self._recursion_depth += 1
if self._recursion_depth > self._max_recursion_depth:
    raise self.parse_error(ParseError, "Maximum nesting depth exceeded")
try:
    # ... existing parsing logic ...
finally:
    self._recursion_depth -= 1

Reporter

Conner Webber ([email protected])


Note: Private vulnerability reporting is not enabled on this repository and no SECURITY.md was found, so this is filed as a public issue. I attempted PVRA first. If maintainers would prefer private coordination, please reach out to the email above.

Activity

  1. frostming commented on Apr 2, 2026

    @frostming
    Contributor

    Thanks, would you like to submit a patch?

  2. spartan8806 commented on Apr 2, 2026

    @spartan8806
    Author

    I would love to! I will get started tomorrow when I get home form work.

  3. added a commit that references this issue on Apr 3, 2026
    6136b84
  4. spartan8806 commented on Apr 3, 2026

    @spartan8806
    Author

    Hey I think its fixed I had opus help and look everything over to make sure I didn't brake anything. Thanks for letting me help.

  5. spartan8806 commented on Jul 11, 2026

    @spartan8806
    Author

    Hey @frostming — I originally reported this recursion DoS in #459, and I see it's now fixed and merged via #510. I did try to fix it myself in #468 at the time, but a family situation pulled me away and I missed your follow-up — sorry about that. Either way, since it's a network-reachable DoS (CVSS ~5.3, CWE-674) in a widely-used library, would you be open to opening a GitHub security advisory for it and requesting a CVE? It'd let dependency scanners (Dependabot/Snyk/etc.) flag the affected versions for downstream users — and honestly it'd help me too (I'm building a security portfolio). For reference, the near-identical recursion DoS in eml_parser's parser.py was assigned CVE-2026-44844, so this class clearly qualifies. If you'd rather not deal with the advisory workflow, no problem — happy to request one myself through a CNA as the reporter. Thanks!

  6. added a commit that references this issue on Jul 26, 2026
  7. added a commit that references this issue on Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions