CVE-2026-71491
CVE-2026-71491 in sqlparse is being characterized as a quadratic parsing vulnerability, but the more important story is what it reveals about API contracts in parsing libraries. The vulnerability triggers through `sqlparse.format(sql, strip_comments=True)` — a convenience method that signals "clean this SQL safely." That's exactly what a developer reaching for this function expects it to do. The problem is that inputs with many comment tokens cause the underlying `group_comments` logic to rescann token sequences, producing quadratic time complexity that makes a seemingly normal operation catastrophically expensive. The EPSS score of 0.00263 suggests low probability of targeted exploitation, but that metric doesn't account for sqlparse's role as infrastructure software. The library is embedded in dozens of downstream tools — SQL formatters, ORM tooling, database migration scripts, security scanners — that normalize SQL from sources that may include untrusted input. A migration tool processing a schema script, or a scanner analyzing submitted SQL, isn't "passing untrusted input" in any way that would trigger suspicion. They're trusting the library's API contract. That contract is now violated for inputs that look entirely normal: SQL with excessive comments is well-formed, not adversarial in any syntactic sense, yet it triggers computational collapse. The fix shipping as version 0.6.0 rather than a patch is significant. This indicates the original `group_comments` implementation encoded an unbounded assumption — that comment density correlates with semantic complexity — rather than a missing guard that could be surgically added. The architectural bet was: comment-stripping is a safe operation on well-formed SQL. That bet failed. What matters now is whether downstream tools that consume sqlparse have updated their own assumptions about what input shapes are safe, or whether they're still operating under the implicit trust model that 0.5.x's behavior encoded. The vulnerability doesn't just live in sqlparse — it lives in every pinned requirements.txt and frozen Docker image that won't see the upgrade.
Reviewed through automated stages and approved by a human before publication.