Skip to content

Commit

Permalink
Fixed catastrophic backtracking in URLValidator.
Browse files Browse the repository at this point in the history
Thanks João Silva for reporting the problem and Tim Graham for finding the
problematic RE and for review.

This is a security fix; disclosure to follow shortly.
  • Loading branch information
shaib authored and timgraham committed Jul 8, 2015
1 parent 014247a commit 17d3a6d
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 1 deletion.
2 changes: 1 addition & 1 deletion django/core/validators.py
Expand Up @@ -73,7 +73,7 @@ class URLValidator(RegexValidator):

# Host patterns
hostname_re = r'[a-z' + ul + r'0-9](?:[a-z' + ul + r'0-9-]*[a-z' + ul + r'0-9])?'
domain_re = r'(?:\.[a-z' + ul + r'0-9]+(?:[a-z' + ul + r'0-9-]*[a-z' + ul + r'0-9]+)*)*'
domain_re = r'(?:\.(?!-)[a-z' + ul + r'0-9-]*(?<!-))*'
tld_re = r'\.(?:[a-z' + ul + r']{2,}|xn--[a-z0-9]+)\.?'
host_re = '(' + hostname_re + domain_re + tld_re + '|localhost)'

Expand Down
7 changes: 7 additions & 0 deletions docs/releases/1.8.3.txt
Expand Up @@ -60,6 +60,13 @@ The undocumented, internally unused ``validate_integer()`` function is now
stricter as it validates using a regular expression instead of simply casting
the value using ``int()`` and checking if an exception was raised.

Denial-of-service possibility in URL validation
===============================================

:class:`~django.core.validators.URLValidator` included a regular expression
that was extremely slow to evaluate against certain invalid inputs. This regular
expression has been simplified and optimized.

Bugfixes
========

Expand Down
2 changes: 2 additions & 0 deletions tests/validators/invalid_urls.txt
Expand Up @@ -35,6 +35,8 @@ http://foo.bar/foo(bar)baz quux
http://-error-.invalid/
http://-a.b.co
http://a.b-.co
http://a.-b.co
http://a.b-.c.co
http:/
http://
http://
Expand Down
3 changes: 3 additions & 0 deletions tests/validators/tests.py
Expand Up @@ -188,6 +188,9 @@
# Trailing newlines not accepted
(URLValidator(), 'http://www.djangoproject.com/\n', ValidationError),
(URLValidator(), 'http://[::ffff:192.9.5.5]\n', ValidationError),
# Trailing junk does not take forever to reject
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br ', ValidationError),
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br z', ValidationError),

(BaseValidator(True), True, None),
(BaseValidator(True), False, ValidationError),
Expand Down
1 change: 1 addition & 0 deletions tests/validators/valid_urls.txt
Expand Up @@ -7,6 +7,7 @@ http://www.example.com/
http://www.example.com:8000/test
http://valid-with-hyphens.com/
http://subdomain.example.com/
http://a.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
http://200.8.9.10/
http://200.8.9.10:8000/test
http://su--b.valid-----hyphens.com/
Expand Down

0 comments on commit 17d3a6d

Please sign in to comment.