mirror / django-1.0.X (http://djangoproject.com/)

Mirror of the 1.0.X maintenance release branch.

Clone this repository (size: 7.5 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/mirror/django-10x/
commit 739: c1bb741671f8
parent 738: 0f7f2dadf114
branch: default
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 will follow.
jacob
5 months ago

Changed (Δ1.1 KB):

raw changeset »

django/forms/fields.py (2 lines added, 2 lines removed)

tests/regressiontests/forms/fields.py (33 lines added, 0 lines removed)

Up to file-list django/forms/fields.py:

@@ -421,7 +421,7 @@ class RegexField(CharField):
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 @@ class ImageField(FileField):
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

Up to file-list tests/regressiontests/forms/fields.py:

@@ -767,6 +767,13 @@ u'example@valid-----hyphens.com'
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 @@ ValidationError: [u'Enter a valid URL.']
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
...