Описание
sqlparse: Quadratic O(n²) DoS in group_comments
Summary
A comment-only statement (-- c\n*n) may cause a Denial of Service (DoS).
Details
Location: sqlparse/engine/grouping.py:331-341 (group_comments), invoked first in group() at grouping.py:439. Reachable via sqlparse.parse() and sqlparse.format(sql, strip_comments=True).
A statement made of many single-line comments ('-- c\n' repeated) lexes in O(n) but group_comments is O(n²):
The while loop runs n times and each token_next_by / token_not_matching rescans the O(n) remaining tokens. When all tokens are comments/newlines nothing ever groups, yet the full scan is repeated per token.
Two following factors increase the severity:
group_commentsruns first ingroup()(grouping.py:439), before the_group_matchingtoken-count guard (grouping.py:34-39). So the entire quadratic cost is paid even on oversized input.MAX_GROUPING_TOKENSdoes not provide protection on this vector.- It sits on the primary sanitizer path:
format(sql, strip_comments=True), used by query loggers, SQL firewalls, ORMs, and migration tools.
PoC
Tested using Python 3.14:
Output:
Time increase of ~4× per 2× input (quadratic). parse() shows the identical curve. Instrumented scan counts are exactly 1.0M / 4.0M / 16.0M tokens for n=1000/2000/4000. A ~250 KB comment-only payload forces minutes of CPU regardless of the 10000 token cap.
Impact
Denial of Service
Пакеты
sqlparse
<= 0.5.5
0.6.0
Связанные уязвимости
sqlparse is a non-validating SQL parser module for Python. Prior to 0.6.0, group_comments in sqlparse/engine/grouping.py repeatedly rescans comment-only statements before the MAX_GROUPING_TOKENS guard, causing quadratic CPU consumption through sqlparse.parse() and sqlparse.format(sql, strip_comments=True). This issue is fixed in version 0.6.0.
sqlparse is a non-validating SQL parser module for Python. Prior to 0.6.0, group_comments in sqlparse/engine/grouping.py repeatedly rescans comment-only statements before the MAX_GROUPING_TOKENS guard, causing quadratic CPU consumption through sqlparse.parse() and sqlparse.format(sql, strip_comments=True). This issue is fixed in version 0.6.0.
sqlparse is a non-validating SQL parser module for Python. Prior to 0. ...