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. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@11605 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
2099aba1bd
commit
594a28a904
|
@ -421,7 +421,7 @@ class RegexField(CharField):
|
||||||
email_re = re.compile(
|
email_re = re.compile(
|
||||||
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
||||||
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
|
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
|
||||||
r')@(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
|
r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain
|
||||||
|
|
||||||
class EmailField(RegexField):
|
class EmailField(RegexField):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
|
@ -532,7 +532,7 @@ class ImageField(FileField):
|
||||||
|
|
||||||
url_re = re.compile(
|
url_re = re.compile(
|
||||||
r'^https?://' # http:// or https://
|
r'^https?://' # http:// or https://
|
||||||
r'(?:(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}|' #domain...
|
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
|
||||||
r'localhost|' #localhost...
|
r'localhost|' #localhost...
|
||||||
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
|
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
|
||||||
r'(?::\d+)?' # optional port
|
r'(?::\d+)?' # optional port
|
||||||
|
|
|
@ -767,6 +767,13 @@ u'example@valid-----hyphens.com'
|
||||||
>>> f.clean('example@valid-with-hyphens.com')
|
>>> f.clean('example@valid-with-hyphens.com')
|
||||||
u'example@valid-with-hyphens.com'
|
u'example@valid-with-hyphens.com'
|
||||||
|
|
||||||
|
# Check for runaway regex security problem. This will take for-freeking-ever
|
||||||
|
# if the security fix isn't in place.
|
||||||
|
>>> f.clean('viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Enter a valid e-mail address.']
|
||||||
|
|
||||||
>>> f = EmailField(required=False)
|
>>> f = EmailField(required=False)
|
||||||
>>> f.clean('')
|
>>> f.clean('')
|
||||||
u''
|
u''
|
||||||
|
@ -972,6 +979,32 @@ ValidationError: [u'Enter a valid URL.']
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValidationError: [u'Enter a valid URL.']
|
ValidationError: [u'Enter a valid URL.']
|
||||||
|
>>> f.clean('.')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Enter a valid URL.']
|
||||||
|
>>> f.clean('com.')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Enter a valid URL.']
|
||||||
|
>>> f.clean('http://example.com.')
|
||||||
|
u'http://example.com./'
|
||||||
|
>>> f.clean('example.com.')
|
||||||
|
u'http://example.com./'
|
||||||
|
|
||||||
|
# hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed
|
||||||
|
>>> f.clean('http://%s' % ("X"*200,))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Enter a valid URL.']
|
||||||
|
|
||||||
|
# a second test, to make sure the problem is really addressed, even on
|
||||||
|
# domains that don't fail the domain label length check in the regex
|
||||||
|
>>> f.clean('http://%s' % ("X"*60,))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Enter a valid URL.']
|
||||||
|
|
||||||
>>> f.clean('http://.com')
|
>>> f.clean('http://.com')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
|
|
Loading…
Reference in New Issue