Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed some missed auto-escaping and URL quoting cases in the urlize f…

…ilter.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6683 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 4585b4d6c23cfad0366480fc1bb03edc34ebe428 1 parent adcec08
Malcolm Tredinnick authored November 17, 2007
19  django/utils/html.py
@@ -6,6 +6,7 @@
6 6
 from django.utils.safestring import SafeData, mark_safe
7 7
 from django.utils.encoding import force_unicode
8 8
 from django.utils.functional import allow_lazy
  9
+from django.utils.http import urlquote
9 10
 
10 11
 # Configuration for urlize() function
11 12
 LEADING_PUNCTUATION  = ['(', '<', '&lt;']
@@ -101,14 +102,24 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
101 102
             if middle.startswith('www.') or ('@' not in middle and not middle.startswith('http://') and \
102 103
                     len(middle) > 0 and middle[0] in string.letters + string.digits and \
103 104
                     (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))):
104  
-                middle = '<a href="http://%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle))
  105
+                middle = '<a href="http://%s"%s>%s</a>' % (
  106
+                        urlquote(middle, safe='/&=:;#?+'),  nofollow_attr,
  107
+                        trim_url(middle))
105 108
             if middle.startswith('http://') or middle.startswith('https://'):
106  
-                middle = '<a href="%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle))
107  
-            if '@' in middle and not middle.startswith('www.') and not ':' in middle \
108  
-                and simple_email_re.match(middle):
  109
+                middle = '<a href="%s"%s>%s</a>' % (
  110
+                        urlquote(middle, safe='/&=:;#?+'), nofollow_attr,
  111
+                        trim_url(middle))
  112
+            if '@' in middle and not middle.startswith('www.') and \
  113
+                    not ':' in middle and simple_email_re.match(middle):
109 114
                 middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
110 115
             if lead + middle + trail != word:
111 116
                 words[i] = lead + middle + trail
  117
+            elif autoescape and not safe_input:
  118
+                words[i] = escape(word)
  119
+        elif safe_input:
  120
+            words[i] = mark_safe(word)
  121
+        elif autoescape:
  122
+            words[i] = escape(word)
112 123
     return u''.join(words)
113 124
 urlize = allow_lazy(urlize, unicode)
114 125
 
5  tests/regressiontests/templates/filters.py
@@ -94,6 +94,11 @@ def get_filter_tests():
94 94
         'filter-urlize03': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": mark_safe("a &amp; b")}, 'a &amp; b'),
95 95
         'filter-urlize04': ('{{ a|urlize }}', {"a": mark_safe("a &amp; b")}, 'a &amp; b'),
96 96
 
  97
+        # This will lead to a nonsense result, but at least it won't be
  98
+        # exploitable for XSS purposes when auto-escaping is on.
  99
+        'filter-urlize05': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": "<script>alert('foo')</script>"}, "<script>alert('foo')</script>"),
  100
+        'filter-urlize06': ('{{ a|urlize }}', {"a": "<script>alert('foo')</script>"}, '&lt;script&gt;alert(&#39;foo&#39;)&lt;/script&gt;'),
  101
+
97 102
         'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/x=&y=" rel="nofollow">http:...</a> <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
98 103
         'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/x=&y=" rel="nofollow">http:...</a> <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
99 104
 

0 notes on commit 4585b4d

Please sign in to comment.
Something went wrong with that request. Please try again.