Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

SECURITY ALERT: Corrected regular expressions for URL and email fields.

Certain email addresses/URLs could trigger a catastrophic backtracking situation, causing 100% CPU and server overload. If deliberately triggered, this could be the basis of a denial-of-service attack.

This security vulnerability was disclosed in public, so we're skipping our
normal security release process to get the fix out as soon as possible.

This is a security related update. A full announcement, as well as backports for the 1.1.X and 1.0.X series will follow.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11603 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9f8287a3f145fe5cbe71ef5573ea8898404727ad 1 parent 8aee95c
Jacob Kaplan-Moss authored October 09, 2009
4  django/forms/fields.py
@@ -421,7 +421,7 @@ def clean(self, value):
421 421
 email_re = re.compile(
422 422
     r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
423 423
     r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
424  
-    r')@(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
  424
+    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
425 425
 
426 426
 class EmailField(RegexField):
427 427
     default_error_messages = {
@@ -532,7 +532,7 @@ def clean(self, data, initial=None):
532 532
 
533 533
 url_re = re.compile(
534 534
     r'^https?://' # http:// or https://
535  
-    r'(?:(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}|' #domain...
  535
+    r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
536 536
     r'localhost|' #localhost...
537 537
     r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
538 538
     r'(?::\d+)?' # optional port
33  tests/regressiontests/forms/fields.py
@@ -767,6 +767,13 @@
767 767
 >>> f.clean('example@valid-with-hyphens.com')
768 768
 u'example@valid-with-hyphens.com'
769 769
 
  770
+# Check for runaway regex security problem. This will take for-freeking-ever
  771
+# if the security fix isn't in place.
  772
+>>> f.clean('viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058')
  773
+Traceback (most recent call last):
  774
+    ...
  775
+ValidationError: [u'Enter a valid e-mail address.']
  776
+
770 777
 >>> f = EmailField(required=False)
771 778
 >>> f.clean('')
772 779
 u''
@@ -972,6 +979,32 @@
972 979
 Traceback (most recent call last):
973 980
 ...
974 981
 ValidationError: [u'Enter a valid URL.']
  982
+>>> f.clean('.')
  983
+Traceback (most recent call last):
  984
+...
  985
+ValidationError: [u'Enter a valid URL.']
  986
+>>> f.clean('com.')
  987
+Traceback (most recent call last):
  988
+...
  989
+ValidationError: [u'Enter a valid URL.']
  990
+>>> f.clean('http://example.com.')
  991
+u'http://example.com./'
  992
+>>> f.clean('example.com.')
  993
+u'http://example.com./'
  994
+
  995
+# hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed
  996
+>>> f.clean('http://%s' % ("X"*200,))
  997
+Traceback (most recent call last):
  998
+...
  999
+ValidationError: [u'Enter a valid URL.']
  1000
+
  1001
+# a second test, to make sure the problem is really addressed, even on 
  1002
+# domains that don't fail the domain label length check in the regex
  1003
+>>> f.clean('http://%s' % ("X"*60,))
  1004
+Traceback (most recent call last):
  1005
+...
  1006
+ValidationError: [u'Enter a valid URL.']
  1007
+
975 1008
 >>> f.clean('http://.com')
976 1009
 Traceback (most recent call last):
977 1010
 ...

0 notes on commit 9f8287a

Please sign in to comment.
Something went wrong with that request. Please try again.