CVE-2026-84305 Overview
CVE-2026-84305 is an algorithmic complexity vulnerability [CWE-407] in sqlparse, a non-validating SQL parser module for Python. The flaw affects versions prior to 0.6.0 when callers use sqlparse.format(sql, reindent=True) or invoke sqlformat --reindent. Attacker-controlled parenthesized tuple lists route through ReindentFilter._get_offset() in sqlparse/filters/reindent.py, where _flatten_up_to_token() repeatedly rebuilds and joins the statement prefix. The result is quadratic CPU consumption for inputs that stay under the MAX_GROUPING_TOKENS cap. Applications that expose SQL formatting to untrusted input face request delays, reduced throughput, and worker starvation. The maintainers fixed the issue in sqlparse 0.6.0.
Critical Impact
A ~12 KB crafted SQL payload can pin a CPU for seconds, degrading availability of any service that reindents attacker-influenced SQL.
Affected Products
- sqlparse versions prior to 0.6.0
- Python applications invoking sqlparse.format(sql, reindent=True)
- Tools and pipelines calling sqlformat --reindent
Discovery Timeline
- 2026-09-01 - CVE-2026-84305 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-84305
Vulnerability Analysis
The defect lives in ReindentFilter._get_offset(), which reports the column at which a token starts. Each call rebuilds the entire statement prefix from the start of the statement and joins its token values into a string. The reindent filter invokes this routine once per group, so a statement containing N parenthesized tuples triggers N offset calculations that each walk an expanding token tree. The overall cost scales as O(N²) in the number of tuples.
An attacker sizes a tuple list to stay just below MAX_GROUPING_TOKENS = 10000, so token grouping succeeds and execution reaches the expensive reindentation path. The behavior applies to IN (...) lists processed by _process_parenthesis() and _process_identifierlist(), and to VALUES lists processed by _process_values(). Benchmarks from the upstream patch show a ~12 KB payload consuming CPU for seconds per request.
Root Cause
_flatten_up_to_token() rebuilds and re-joins the statement prefix on every offset lookup instead of measuring the current line by walking backward from the target token. Repeated forward traversal over an ever-growing prefix is the source of the quadratic behavior.
Attack Vector
Exploitation requires that an application pass attacker-controlled SQL through the opt-in reindent=True formatting path. Common exposure surfaces include developer tooling, log pretty-printers, SQL review services, and web endpoints that echo or normalize user-supplied queries. The attacker submits a large tuple list crafted to remain below the grouping-token cap, which forces the reindent filter to enter the quadratic offset calculation.
* Fix uncontrolled CPU consumption when reindenting long tuple lists
(CWE-1333, GHSA-cfqr-cjx5-5jcm). ReindentFilter._get_offset() rebuilt
the statement prefix from its start on every call, making format() with
reindent=True O(N^2) in the number of tuples. Fix: measure the current
line by walking backwards from the token. Output is unchanged.
Source: GitHub Commit a51df6d
Detection Methods for CVE-2026-84305
Indicators of Compromise
- Sustained single-core CPU saturation in Python worker processes hosting sqlparse.
- Request latency spikes correlated with inbound SQL payloads containing very long IN (...) or VALUES tuple lists.
- Application logs showing sqlparse.format or sqlformat calls immediately preceding worker timeouts.
Detection Strategies
- Inventory Python dependencies for sqlparse versions below 0.6.0 using SBOM tooling or pip list.
- Instrument code paths that call sqlparse.format(..., reindent=True) with per-call duration metrics and alert on outliers.
- Add request-size and tuple-count limits at the application layer before SQL enters the reindent path.
Monitoring Recommendations
- Track worker CPU time, event-loop stalls, and 5xx rates on endpoints that accept SQL text.
- Emit structured logs that capture payload size and parenthesis count for SQL passed to formatters.
- Correlate resource-exhaustion alerts with source IPs that submit unusually large SQL bodies.
How to Mitigate CVE-2026-84305
Immediate Actions Required
- Upgrade sqlparse to version 0.6.0 or later across all Python services and container images.
- Audit application entry points that pass untrusted SQL to sqlparse.format with reindent=True or to the sqlformat CLI.
- Apply request-body size limits and per-request CPU or wall-clock timeouts to formatter endpoints.
Patch Information
The fix landed in commit a51df6d9e2d31b44be9adb6bc8732517db6bf96b and shipped in sqlparse 0.6.0. The patch changes _get_offset() to measure the current line by walking backward from the token, producing identical output without the quadratic cost. See the GitHub Security Advisory GHSA-cfqr-cjx5-5jcm for the coordinated advisory.
Workarounds
- Disable reindent=True and avoid sqlformat --reindent for untrusted input until the upgrade is deployed.
- Reject SQL payloads that exceed a conservative byte length or parenthesized-tuple count at the ingress layer.
- Execute SQL formatting in an isolated worker pool with strict CPU and time limits to contain resource exhaustion.
# Upgrade sqlparse to the patched release
pip install --upgrade 'sqlparse>=0.6.0'
# Verify the installed version
python -c "import sqlparse; print(sqlparse.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

