CVE-2026-59893 Overview
CVE-2026-59893 is a regular expression denial of service (ReDoS) vulnerability in sqlparse, a non-validating SQL parser module for Python. Versions prior to 0.6.0 contain lazy dot-all regexes in SQL_REGEX (sqlparse/keywords.py) and a per-position loop in sqlparse/lexer.py that repeatedly rescan unmatched dollar-quoted literal and multiline-comment delimiters. Attacker-supplied SQL text passed to sqlparse.parse(), sqlparse.format(), or sqlparse.split() triggers quadratic CPU consumption. The issue is fixed in version 0.6.0 and is classified under CWE-1333.
Critical Impact
Remote, unauthenticated attackers can force O(n²) CPU work in any application that parses untrusted SQL through sqlparse, resulting in denial of service.
Affected Products
- sqlparse versions prior to 0.6.0
- Python applications and frameworks that pass untrusted SQL to sqlparse.parse(), sqlparse.format(), or sqlparse.split()
- Downstream tooling that depends on sqlparse for SQL formatting, linting, or splitting
Discovery Timeline
- Reported by EQSTLab (per the upstream advisory GHSA-prg7-hcfm-mfcr)
- 2026-08-17 - CVE-2026-59893 published to NVD
- 2026-08-17 - Last updated in NVD database
Technical Details for CVE-2026-59893
Vulnerability Analysis
The flaw is an algorithmic complexity issue in the sqlparse lexer. Three regexes rely on a lazy dot-all quantifier ([\s\S]*?) terminated by either a backreference or a literal delimiter. The lexer applies these patterns at every text position in a loop. When an opener has no matching closer, each application must rescan the remaining input to the end. With many unique unmatched openers, total work grows quadratically with input length.
The two vulnerable constructs are dollar-quoted literals, such as $tag$ ... $tag$, and multiline comments delimited by /* and */. Both are legal SQL syntax that a parser must tolerate, so input filtering upstream is insufficient. Availability is the sole impact; confidentiality and integrity are not affected.
Root Cause
The upstream fix resolves delimiter pairs in a single linear pass instead of re-scanning per opener, eliminating the O(n²) behavior.
Security Fixes
* Fix uncontrolled CPU consumption (ReDoS) in the lexer's handling of
dollar-quoted literals and multiline comments (CWE-1333,
GHSA-prg7-hcfm-mfcr, reported by EQSTLab). Three regexes used a lazy
dot-all quantifier (``[\s\S]*?``) terminated by a backreference or a
literal delimiter, applied at every text position by the lexer loop;
unclosed openers therefore forced a full rescan of the remaining input
per opener, costing O(n²) CPU on crafted SQL with many unique unmatched
``$tag$`` or ``/*`` openers. Fix: resolve delimiter pairs in a single
linear pass instead of re-scanning per opener.
Source: sqlparse commit d1d80602741f77ec78e5a04ce4719244cf32352e
Attack Vector
An unauthenticated network attacker submits crafted SQL text to any endpoint that ultimately calls sqlparse. Payloads take the form $a0$x $a1$x ... $aN$x for dollar-quoted literals or /* unique0 ... /* unique1 ... for multiline comments. The upstream benchmark demonstrates the scaling behavior.
"""Delimited-literal lexer benchmark (GHSA-prg7-hcfm-mfcr).
Measures parse time for SQL text containing many unique, unmatched
opening delimiters for the two lexer constructs that used a lazy dot-all
regex (`[\\s\\S]*?`) terminated by a backreference or a literal closing
sequence:
- Dollar-quoted literals, e.g. `$a0$x $a1$x ... $aN$x` (backreference).
- Multiline comments, e.g. `/* unique0 ... /* unique1 ...` (literal `*/`).
When no closing delimiter is present, a lazy dot-all quantifier applied at
every text position must scan to the end of the remaining input for every
opener, which is O(n^2) total work as the number of openers grows.
"""
import signal
import time
import sqlparse
from sqlparse.engine import grouping
Source: benchmarks/bench_dollar_quote_redos.py
Detection Methods for CVE-2026-59893
Indicators of Compromise
- Python worker or web-server processes pinned at 100% CPU while handling requests that carry SQL input.
- Request bodies or query parameters containing large numbers of unique $tag$ sequences without matching closers.
- Request bodies containing repeated unmatched /* sequences without corresponding */ terminators.
- Request timeouts, worker restarts, or gunicorn/uwsgi kill signals correlated with SQL-parsing endpoints.
Detection Strategies
- Inventory dependencies with pip show sqlparse or SBOM tooling and flag any version below 0.6.0.
- Add application-layer logging around calls to sqlparse.parse(), sqlparse.format(), and sqlparse.split() to record input length and execution time.
- Deploy WAF or reverse-proxy rules that count unmatched $...$ and /* tokens per request and reject outliers.
Monitoring Recommendations
- Alert on sustained CPU saturation in Python processes that host SQL-facing endpoints such as Django admin, database GUIs, or SQL formatters.
- Track p95/p99 latency of endpoints that invoke sqlparse and investigate regressions.
- Correlate high-CPU intervals with request logs to identify offending source IPs and payload signatures.
How to Mitigate CVE-2026-59893
Immediate Actions Required
- Upgrade sqlparse to version 0.6.0 or later across all Python environments and container images.
- Rebuild and redeploy applications that vendor sqlparse as a transitive dependency, including Django-based stacks.
- Enforce request size limits and execution timeouts on endpoints that accept SQL input from untrusted sources.
- Rate-limit unauthenticated endpoints that expose SQL parsing or formatting features.
Patch Information
The fix is delivered in sqlparse 0.6.0. The upstream commit rewrites the affected lexer paths to resolve delimiter pairs in a single linear pass. Review the GitHub Security Advisory GHSA-prg7-hcfm-mfcr and the remediation commit for full details.
Workarounds
- Cap input length before calling sqlparse when an immediate upgrade is not possible.
- Wrap sqlparse calls in a bounded worker or subprocess with a CPU/time budget enforced by signal.alarm or a process supervisor.
- Reject or sanitize inputs with abnormally high counts of $ or /* tokens at the WAF or application ingress.
# Upgrade sqlparse to the fixed release
pip install --upgrade 'sqlparse>=0.6.0'
# Verify the installed version
python -c "import sqlparse; print(sqlparse.__version__)"
# Audit environments for vulnerable installs
pip list --format=freeze | grep -i '^sqlparse=='
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

