CVE-2023-30608: Inefficient Regular Expression Complexity (CWE-1333)
value: sqlparse is a non-validating SQL parser module for Python. In affected versions the SQL parser contains a regular expression that is vulnerable to ReDoS (Regular Expression Denial of Service). This issue was introduced by commit `e75e358`. The vulnerability may lead to Denial of Service (DoS). This issues has been fixed in sqlparse 0.4.4 by commit `c457abd5f`. Users are advised to upgrade. There are no known workarounds for this issue.

CWE description: The product uses a regular expression with an inefficient, possibly exponential worst-case computational complexity that consumes excessive CPU cycles.
CVSS v3 base score: 7.5
Published: 2023-04-18T22:15Z
Repository: https://github.com/andialbrecht/sqlparse
Language: Python
Files changed: CHANGELOG, sqlparse/keywords.py, tests/test_split.py
Commit date: 2023-04-18 10:23:02 +0200
Commit message: Remove unnecessary parts in regex for bad escaping.

The regex tried to deal with situations where escaping in the
SQL to be parsed was suspicious.

Diff: diff --git a/CHANGELOG b/CHANGELOG
index 9486413..880a9ca 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,14 +1,24 @@
 Development Version
 -------------------
 
+Notable Changes
+
+* IMPORTANT: This release fixes a security vulnerability in the
+  parser where a regular expression vulnerable to ReDOS (Regular
+  Expression Denial of Service) was used. See the security advisory
+  for details: https://github.com/andialbrecht/sqlparse/security/advisories/GHSA-rrm6-wvj7-cwh2
+  The vulnerability was discovered by @erik-krogh from GitHub
+  Security Lab (GHSL). Thanks for reporting!
+
 Bug Fixes
 
 * Revert a change from 0.4.0 that changed IN to be a comparison (issue694).
   The primary expectation is that IN is treated as a keyword and not as a
   comparison operator. That also follows the definition of reserved keywords
   for the major SQL syntax definitions.
+* Fix regular expressions for string parsing.
 
 Other
 
 * sqlparse now uses pyproject.toml instead of setup.cfg (issue685).
 
diff --git a/sqlparse/keywords.py b/sqlparse/keywords.py
index f85d468..b45f3e0 100644
--- a/sqlparse/keywords.py
+++ b/sqlparse/keywords.py
@@ -57,13 +57,13 @@ SQL_REGEX = [
     (r'-?0x[\dA-F]+', tokens.Number.Hexadecimal),
     (r'-?\d+(\.\d+)?E-?\d+', tokens.Number.Float),
     (r'(?![_A-ZÀ-Ü])-?(\d+(\.\d*)|\.\d+)(?![_A-ZÀ-Ü])',
      tokens.Number.Float),
     (r'(?![_A-ZÀ-Ü])-?\d+(?![_A-ZÀ-Ü])', tokens.Number.Integer),
-    (r"'(''|\\\\|\\'|[^'])*'", tokens.String.Single),
+    (r"'(''|\\'|[^'])*'", tokens.String.Single),
     # not a real string literal in ANSI SQL:
-    (r'"(""|\\\\|\\"|[^"])*"', tokens.String.Symbol),
+    (r'"(""|\\"|[^"])*"', tokens.String.Symbol),
     (r'(""|".*?[^\\]")', tokens.String.Symbol),
     # sqlite names can be escaped with [square brackets]. left bracket
     # cannot be preceded by word character or a right bracket --
     # otherwise it's probably an array index
     (r'(?<![\w\])])(\[[^\]\[]+\])', tokens.Name),
diff --git a/tests/test_split.py b/tests/test_split.py
index a9d7576..e79750e 100644
--- a/tests/test_split.py
+++ b/tests/test_split.py
@@ -16,12 +16,12 @@ def test_split_semicolon():
     assert str(stmts[0]) == sql1
     assert str(stmts[1]) == sql2
 
 
 def test_split_backslash():
-    stmts = sqlparse.parse(r"select '\\'; select '\''; select '\\\'';")
-    assert len(stmts) == 3
+    stmts = sqlparse.parse("select '\'; select '\'';")
+    assert len(stmts) == 2
 
 
 @pytest.mark.parametrize('fn', ['function.sql',
                                 'function_psql.sql',
                                 'function_psql2.sql',

Vulnerable code:     (r"'(''|\\\\|\\'|[^'])*'", tokens.String.Single),
    (r'"(""|\\\\|\\"|[^"])*"', tokens.String.Symbol),
    stmts = sqlparse.parse(r"select '\\'; select '\''; select '\\\'';")
    assert len(stmts) == 3
Fixed code: Notable Changes

* IMPORTANT: This release fixes a security vulnerability in the
  parser where a regular expression vulnerable to ReDOS (Regular
  Expression Denial of Service) was used. See the security advisory
  for details: https://github.com/andialbrecht/sqlparse/security/advisories/GHSA-rrm6-wvj7-cwh2
  The vulnerability was discovered by @erik-krogh from GitHub
  Security Lab (GHSL). Thanks for reporting!

* Fix regular expressions for string parsing.
    (r"'(''|\\'|[^'])*'", tokens.String.Single),
    (r'"(""|\\"|[^"])*"', tokens.String.Symbol),
    stmts = sqlparse.parse("select '\'; select '\'';")
    assert len(stmts) == 2