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.
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] |
|
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] |
|
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 |
... |
