File tree 3 files changed +30
-6
lines changed
3 files changed +30
-6
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,11 @@ Notable Changes
5
5
6
6
* Drop support for Python 3.5, 3.6, and 3.7.
7
7
* Python 3.12 is now supported (pr725, by hugovk).
8
+ * IMPORTANT: Fixes a potential denial of service attack (DOS) due to recursion
9
+ error for deeply nested statements. Instead of recursion error a generic
10
+ SQLParseError is raised. See the security advisory for details:
11
+ https://github.com/andialbrecht/sqlparse/security/advisories/GHSA-2m57-hf25-phgg
12
+ The vulnerability was discovered by @uriyay-jfrog. Thanks for reporting!
8
13
9
14
Enhancements:
10
15
Original file line number Diff line number Diff line change 10
10
import re
11
11
12
12
from sqlparse import tokens as T
13
+ from sqlparse .exceptions import SQLParseError
13
14
from sqlparse .utils import imt , remove_quotes
14
15
15
16
@@ -209,11 +210,14 @@ def flatten(self):
209
210
210
211
This method is recursively called for all child tokens.
211
212
"""
212
- for token in self .tokens :
213
- if token .is_group :
214
- yield from token .flatten ()
215
- else :
216
- yield token
213
+ try :
214
+ for token in self .tokens :
215
+ if token .is_group :
216
+ yield from token .flatten ()
217
+ else :
218
+ yield token
219
+ except RecursionError as err :
220
+ raise SQLParseError ('Maximum recursion depth exceeded' ) from err
217
221
218
222
def get_sublists (self ):
219
223
for token in self .tokens :
Original file line number Diff line number Diff line change 1
1
import copy
2
+ import sys
2
3
3
4
import pytest
4
5
5
6
import sqlparse
6
7
from sqlparse import sql , tokens as T
8
+ from sqlparse .exceptions import SQLParseError
7
9
8
10
9
11
def test_issue9 ():
@@ -449,4 +451,17 @@ def test_copy_issue672():
449
451
def test_primary_key_issue740 ():
450
452
p = sqlparse .parse ('PRIMARY KEY' )[0 ]
451
453
assert len (p .tokens ) == 1
452
- assert p .tokens [0 ].ttype == T .Keyword
454
+ assert p .tokens [0 ].ttype == T .Keyword
455
+
456
+
457
+ @pytest .fixture
458
+ def limit_recursion ():
459
+ curr_limit = sys .getrecursionlimit ()
460
+ sys .setrecursionlimit (70 )
461
+ yield
462
+ sys .setrecursionlimit (curr_limit )
463
+
464
+
465
+ def test_max_recursion (limit_recursion ):
466
+ with pytest .raises (SQLParseError ):
467
+ sqlparse .parse ('[' * 100 + ']' * 100 )
You can’t perform that action at this time.
0 commit comments