CVE-2026-71491

highpriority · track · 0EPSS 0.003 · 18 %ileDEEUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.26% (18th) EPSS
CVSS 8.7 · high
Is it mine?
6 products
Check your exposure
Who says so?
3 sources
enisa_euvd · osv · cert_bund

EPSS · scored 2026-10-28

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.

01

cvss

Technical severity, 0–10. One row per scoring source.

8.7
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · medium–high · 6.6–8.7

v4.08.7highCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:Nsecondary · ENISA EU
v4.08.7highCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · security-advisories@github.com
v4.06.6mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: none · Automatable: yes · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (6)

Products and version ranges known to be affected.

05

advisories (3)

Vendor and ecosystem advisories describing this.

  • WID-SEC-W-2026-3555Red Hat Ansible Automation Platform (automation-controller): Mehrere SchwachstellenDeutsch2026-09-23csaf · cert_bundDE

    Ein Angreifer kann mehrere Schwachstellen in Red Hat Ansible Automation Platform ausnutzen, um seine Privilegien zu erhöhen, beliebigen Code auszuführen, Sicherheitsmaßnahmen zu umgehen, Daten zu manipulieren oder offenzulegen und einen Denial-of-Service-Zustand herbeizuführen.

  • GHSA-f2ff-p2ww-7p4psqlparse: Quadratic O(n²) DoS in group_comments2026-08-17ghsa · osvUS

    ### Summary A comment-only statement (`-- c\n`*n) may cause a Denial of Service (DoS). ### Details Location: [sqlparse/engine/grouping.py:331-341](https://github.com/andialbrecht/sqlparse/blob/f80af6a4007f11ada847218df8c29dc859238290/sqlparse/engine/grouping.py#L332) (`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²): ```python def group_comments(tlist): tidx, token = tlist.token_next_by(t=T.Comment) while token: eidx, end = tlist.token_not_matching( lambda tk: imt(tk, t=T.Comment) or tk.is_newline, idx=tidx) ... tidx, token = tlist.token_next_by(t=T.Comment, idx=tidx) ``` 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: 1. `group_comments` runs first in `group()` (`grouping.py:439`), before the `_group_matching` token-count guard (`grouping.py:34-39`). So the entire quadratic cost is paid even on oversized input. `MAX_GROUPING_TOKENS` does not provide protection on this vector. 2. 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: ```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} format(strip_comments)={1000*(time.perf_counter()-t):7.1f} ms") ``` Output: ``` n= 1000 format(strip_comments)= 106.0 ms n= 2000 format(strip_comments)= 403.3 ms n= 4000 format(strip_comments)= 1602.8 ms ``` 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

  • PYSEC-2026-3697sqlparse: Quadratic O(n²) DoS in group_comments2026-08-19vendor · osvUS

    ### Summary A comment-only statement (`-- c\n`*n) may cause a Denial of Service (DoS). ### Details Location: [sqlparse/engine/grouping.py:331-341](https://github.com/andialbrecht/sqlparse/blob/f80af6a4007f11ada847218df8c29dc859238290/sqlparse/engine/grouping.py#L332) (`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²): ```python def group_comments(tlist): tidx, token = tlist.token_next_by(t=T.Comment) while token: eidx, end = tlist.token_not_matching( lambda tk: imt(tk, t=T.Comment) or tk.is_newline, idx=tidx) ... tidx, token = tlist.token_next_by(t=T.Comment, idx=tidx) ``` 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: 1. `group_comments` runs first in `group()` (`grouping.py:439`), before the `_group_matching` token-count guard (`grouping.py:34-39`). So the entire quadratic cost is paid even on oversized input. `MAX_GROUPING_TOKENS` does not provide protection on this vector. 2. 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: ```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} format(strip_comments)={1000*(time.perf_counter()-t):7.1f} ms") ``` Output: ``` n= 1000 format(strip_comments)= 106.0 ms n= 2000 format(strip_comments)= 403.3 ms n= 4000 format(strip_comments)= 1602.8 ms ``` 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

06

also known as (4)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-08-17modified 2026-10-23
08

references (4)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan