mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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): | ||||||
| ... | ... | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user