highCVE-2026-71491Aug 17, 2026

CVE-2026-71491: sqlparse Quadratic DoS in group_comments

Rohit Hatagale
AI Security Researcher, SecureLayer7

Sending a large block of single-line SQL comments to sqlparse causes the parser to hang for minutes, because the comment-grouping function scans all remaining tokens on every loop iteration instead…

Packagesqlparse
Ecosystempip
Affected<= 0.5.5
Fixed in0.6.0
CVE-2026-71491: sqlparse Quadratic DoS in group_comments

The problem

The group_comments function in sqlparse/engine/grouping.py (lines 331-341) uses a while loop that calls token_next_by and token_not_matching on each iteration. Both helpers rescan the token list from the current index each time.

Because comment-only input never produces grouped tokens, the scan count grows as n² for n comment tokens. A ~250 KB payload of '-- c\n' repeated forces roughly 16 million token scans at n=4000, pinning a CPU core for over a second. At larger sizes, the cost reaches minutes.

The MAX_GROUPING_TOKENS guard does not protect this path because group_comments runs first in group(), before that check is applied.

Proof of concept

A working proof-of-concept for CVE-2026-71491 in sqlparse, with the exact payload below.

python
import time, sqlparse
for n in (1000, 2000, 4000):
    s = "-- c\n" * n
    t = time.perf_counter()
    sqlparse.format(s, strip_comments=True)
    print(f"n={n:5d}  {1000*(time.perf_counter()-t):7.1f} ms")
# n= 1000   106.0 ms
# n= 2000   403.3 ms
# n= 4000  1602.8 ms  (~4x per 2x input = O(n²))

The root cause is CWE-407 (Inefficient Algorithmic Complexity). token_next_by and token_not_matching both walk the token list linearly from tidx on every call. When all tokens are comments or newlines, nothing is ever collapsed into a group, so the while loop runs n times and each pass pays O(n) cost, giving O(n²) total.

The patch (commit ef2012a5eeb491e604dea2b00d516904a3830c87) moves the MAX_GROUPING_TOKENS guard to execute before group_comments is entered, so oversized comment-only inputs are rejected early. This closes the bypass where the existing token-count cap was unreachable on this specific code path.

The vulnerability is especially impactful on the format(sql, strip_comments=True) call path, which is widely used by query loggers, SQL firewalls, ORMs, and migration tools processing untrusted SQL.

The fix

Upgrade sqlparse to 0.6.0 or later. The fix ensures MAX_GROUPING_TOKENS (default 10,000) is enforced before group_comments runs. If you cannot upgrade immediately, pre-filter or size-cap input before passing it to sqlparse.parse() or sqlparse.format().

Reporter not attributed.

References: [1][2][3]

Related research