Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite052d40

Browse files
benjaminptim-one
andauthored
[2.7] bpo-32981: Fix catastrophic backtracking vulns (pythonGH-5955)
* Prevent low-grade poplib REDOS (CVE-2018-1060)The regex to test a mail server's timestamp is susceptible tocatastrophic backtracking on long evil responses from the server.Happily, the maximum length of malicious inputs is 2K thanksto a limit introduced in the fix for CVE-2013-1752.A 2KB evil response from the mail server would result in small slowdowns(milliseconds vs. microseconds) accumulated over many apop calls.This is a potential DOS vector via accumulated slowdowns.Replace it with a similar non-vulnerable regex.The new regex is RFC compliant.The old regex was non-compliant in edge cases.* Prevent difflib REDOS (CVE-2018-1061)The default regex for IS_LINE_JUNK is susceptible tocatastrophic backtracking.This is a potential DOS vector.Replace it with an equivalent non-vulnerable regex.Also introduce unit and REDOS tests for difflib.Co-authored-by: Tim Peters <tim.peters@gmail.com>Co-authored-by: Christian Heimes <christian@python.org>.(cherry picked from commit0e6c8ee)
1 parent20003f9 commite052d40

File tree

6 files changed

+39
-3
lines changed

6 files changed

+39
-3
lines changed

‎Lib/difflib.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ def _qformat(self, aline, bline, atags, btags):
11031103

11041104
importre
11051105

1106-
defIS_LINE_JUNK(line,pat=re.compile(r"\s*#?\s*$").match):
1106+
defIS_LINE_JUNK(line,pat=re.compile(r"\s*(?:#\s*)?$").match):
11071107
r"""
11081108
Return 1 for ignorable line: iff `line` is blank or contains a single '#'.
11091109

‎Lib/poplib.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def rpop(self, user):
274274
returnself._shortcmd('RPOP %s'%user)
275275

276276

277-
timestamp=re.compile(r'\+OK.*(<[^>]+>)')
277+
timestamp=re.compile(br'\+OK.[^<]*(<.*>)')
278278

279279
defapop(self,user,secret):
280280
"""Authorisation

‎Lib/test/test_difflib.py‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,33 @@ def test_range_format_context(self):
269269
self.assertEqual(fmt(3,6),'4,6')
270270
self.assertEqual(fmt(0,0),'0')
271271

272+
classTestJunkAPIs(unittest.TestCase):
273+
deftest_is_line_junk_true(self):
274+
forlinein ['#',' ',' #','# ',' # ','']:
275+
self.assertTrue(difflib.IS_LINE_JUNK(line),repr(line))
276+
277+
deftest_is_line_junk_false(self):
278+
forlinein ['##',' ##','## ','abc ','abc #','Mr. Moose is up!']:
279+
self.assertFalse(difflib.IS_LINE_JUNK(line),repr(line))
280+
281+
deftest_is_line_junk_REDOS(self):
282+
evil_input= ('\t'*1000000)+'##'
283+
self.assertFalse(difflib.IS_LINE_JUNK(evil_input))
284+
285+
deftest_is_character_junk_true(self):
286+
forcharin [' ','\t']:
287+
self.assertTrue(difflib.IS_CHARACTER_JUNK(char),repr(char))
288+
289+
deftest_is_character_junk_false(self):
290+
forcharin ['a','#','\n','\f','\r','\v']:
291+
self.assertFalse(difflib.IS_CHARACTER_JUNK(char),repr(char))
272292

273293
deftest_main():
274294
difflib.HtmlDiff._default_prefix=0
275295
Doctests=doctest.DocTestSuite(difflib)
276296
run_unittest(
277297
TestWithAscii,TestAutojunk,TestSFpatches,TestSFbugs,
278-
TestOutputFormat,Doctests)
298+
TestOutputFormat,TestJunkAPIs)
279299

280300
if__name__=='__main__':
281301
test_main()

‎Lib/test/test_poplib.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ def test_noop(self):
211211
deftest_rpop(self):
212212
self.assertOK(self.client.rpop('foo'))
213213

214+
deftest_apop_REDOS(self):
215+
# Replace welcome with very long evil welcome.
216+
# NB The upper bound on welcome length is currently 2048.
217+
# At this length, evil input makes each apop call take
218+
# on the order of milliseconds instead of microseconds.
219+
evil_welcome=b'+OK'+ (b'<'*1000000)
220+
withtest_support.swap_attr(self.client,'welcome',evil_welcome):
221+
# The evil welcome is invalid, so apop should throw.
222+
self.assertRaises(poplib.error_proto,self.client.apop,'a','kb')
223+
214224
deftest_top(self):
215225
expected= ('+OK 116 bytes',
216226
['From: postmaster@python.org','Content-Type: text/plain',

‎Misc/ACKS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ Jonathan Dasteel
318318
Pierre-Yves David
319319
A. Jesse Jiryu Davis
320320
Jake Davis
321+
Jamie (James C.) Davis
322+
Ratnadeep Debnath
321323
Merlijn van Deen
322324
John DeGood
323325
Ned Deily
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Regexes in difflib and poplib were vulnerable to catastrophic backtracking.
2+
These regexes formed potential DOS vectors (REDOS). They have been
3+
refactored. This resolves CVE-2018-1060 and CVE-2018-1061.
4+
Patch by Jamie Davis.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp