[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: XSS in paste 1.7.1-1 and 1.7.3.1-1



Hi,

Could someone take a look at paste in stable-proposed-updates?

(sorry for not sending this mail to -release earlier, I was convinced
that uploading to stable/stable-proposed-updated is enough now, I
probably misread one of the mails on -release)

[Piotr Ożarowski, 2010-06-26]
> Hi guys,
> 
> source package name: paste
> binary package name: python-paste
> 
> affected versions: 1.7.1-1 (stable), 1.7.3.1-1 (testing)
> fixed versions: 1.7.4-1 (unstable)
> 
> backported fix for 1.7.1-1 attached (patch and debdiff)
> 
> what it fixes:
>  URLs like "http://foo.pl/-->%0D<script>alert('xss')</script>"
>  will no longer generate error pages where JavaScript can be executed
> 
> from upstream's changelog:
>  Fix XSS bug (security issue) with not found handlers for
>  :class:`paste.urlparser.StaticURLParser` and
>  :class:`paste.urlmap.URLMap`.  If you ask for a path with
>  ``/--><script>...`` that will be inserted in the error page and can
>  execute Javascript.  Reported by Tim Wintle.
> 
> in paste 1.7.4-1 source package there are two tests, one in
> tests/test_urlmap.py (test_404) and one in tests/test_urlparser.py
> (test_xss)
-- 
Piotr Ożarowski                         Debian GNU/Linux Developer
www.ozarowski.pl          www.griffith.cc           www.debian.org
GPG Fingerprint: 1D2F A898 58DA AF62 1786 2DF7 AEF6 F1A2 A745 7645
diff -u paste-1.7.1/debian/changelog paste-1.7.1/debian/changelog
--- paste-1.7.1/debian/changelog
+++ paste-1.7.1/debian/changelog
@@ -1,3 +1,11 @@
+paste (1.7.1-1+lenny1) stable; urgency=high
+
+  * Fix XSS bug (security issue) with not found handlers for
+    paste.urlparser.StaticURLParser and paste.urlmap.URLMap
+    (patch backported from version 1.7.4)
+
+ -- Piotr Ożarowski <piotr@debian.org>  Fri, 25 Jun 2010 20:47:36 +0200
+
 paste (1.7.1-1) unstable; urgency=low
 
   * New upstream release
diff -u paste-1.7.1/debian/patches/00list paste-1.7.1/debian/patches/00list
--- paste-1.7.1/debian/patches/00list
+++ paste-1.7.1/debian/patches/00list
@@ -1,0 +2 @@
+xss_in_url.dpatch
only in patch2:
unchanged:
--- paste-1.7.1.orig/debian/patches/xss_in_url.dpatch
+++ paste-1.7.1/debian/patches/xss_in_url.dpatch
@@ -0,0 +1,74 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+##
+## DP: Fix XSS bug (security issue) with not found handlers for
+## DP: `paste.urlparser.StaticURLParser` and `paste.urlmap.URLMap`.
+## DP: If you ask for a path with `/--><script>...` that will be
+## DP: inserted in the error page and can execute Javascript.
+## DP: Reported by Tim Wintle.
+
+
+@DPATCH@
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' paste-1.7.1~/paste/httpexceptions.py paste-1.7.1/paste/httpexceptions.py
+--- paste-1.7.1~/paste/httpexceptions.py	2008-06-13 18:41:58.000000000 +0200
++++ paste-1.7.1/paste/httpexceptions.py	2010-06-25 23:33:56.560406133 +0200
+@@ -77,7 +77,7 @@
+ from paste.wsgilib import catch_errors_app
+ from paste.response import has_header, header_value, replace_header
+ from paste.request import resolve_relative_url
+-from paste.util.quoting import strip_html, html_quote, no_quote
++from paste.util.quoting import strip_html, html_quote, no_quote, comment_quote
+ 
+ SERVER_NAME = 'WSGI Server'
+ TEMPLATE = """\
+@@ -210,12 +210,12 @@
+ 
+     def plain(self, environ):
+         """ text/plain representation of the exception """
+-        body = self.make_body(environ, strip_html(self.template), no_quote)
++        body = self.make_body(environ, strip_html(self.template), comment_quote)
+         return ('%s %s\r\n%s\r\n' % (self.code, self.title, body))
+ 
+     def html(self, environ):
+         """ text/html representation of the exception """
+-        body = self.make_body(environ, self.template, html_quote, no_quote)
++        body = self.make_body(environ, self.template, html_quote, comment_quote)
+         return TEMPLATE % {
+                    'title': self.title,
+                    'code': self.code,
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' paste-1.7.1~/paste/urlmap.py paste-1.7.1/paste/urlmap.py
+--- paste-1.7.1~/paste/urlmap.py	2008-06-13 18:41:58.000000000 +0200
++++ paste-1.7.1/paste/urlmap.py	2010-06-25 23:33:56.560406133 +0200
+@@ -7,6 +7,7 @@
+ from UserDict import DictMixin
+ import re
+ import os
++import cgi
+ from paste import httpexceptions
+ 
+ __all__ = ['URLMap', 'PathProxyURLMap']
+@@ -105,7 +106,7 @@
+         extra += '\nHTTP_HOST: %r' % environ.get('HTTP_HOST')
+         app = httpexceptions.HTTPNotFound(
+             environ['PATH_INFO'],
+-            comment=extra).wsgi_application
++            comment=cgi.escape(extra)).wsgi_application
+         return app(environ, start_response)
+ 
+     def normalize_url(self, url, trim=True):
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' paste-1.7.1~/paste/util/quoting.py paste-1.7.1/paste/util/quoting.py
+--- paste-1.7.1~/paste/util/quoting.py	2008-06-13 18:41:58.000000000 +0200
++++ paste-1.7.1/paste/util/quoting.py	2010-06-25 23:33:56.560406133 +0200
+@@ -72,6 +72,13 @@
+     """
+     return s
+ 
++_comment_quote_re = re.compile(r'\-\s*\>')
++def comment_quote(s):
++    """
++    Quote that makes sure text can't escape a comment
++    """
++    return _comment_quote_re.sub('-&gt', str(s))
++
+ url_quote = urllib.quote
+ url_unquote = urllib.unquote
+ 
diff -ruN paste-1.7.1.orig/paste/httpexceptions.py paste-1.7.1/paste/httpexceptions.py
--- paste-1.7.1.orig/paste/httpexceptions.py	2008-06-13 18:41:58.000000000 +0200
+++ paste-1.7.1/paste/httpexceptions.py	2010-06-25 23:48:18.223905611 +0200
@@ -77,7 +77,7 @@
 from paste.wsgilib import catch_errors_app
 from paste.response import has_header, header_value, replace_header
 from paste.request import resolve_relative_url
-from paste.util.quoting import strip_html, html_quote, no_quote
+from paste.util.quoting import strip_html, html_quote, no_quote, comment_quote
 
 SERVER_NAME = 'WSGI Server'
 TEMPLATE = """\
@@ -210,12 +210,12 @@
 
     def plain(self, environ):
         """ text/plain representation of the exception """
-        body = self.make_body(environ, strip_html(self.template), no_quote)
+        body = self.make_body(environ, strip_html(self.template), comment_quote)
         return ('%s %s\r\n%s\r\n' % (self.code, self.title, body))
 
     def html(self, environ):
         """ text/html representation of the exception """
-        body = self.make_body(environ, self.template, html_quote, no_quote)
+        body = self.make_body(environ, self.template, html_quote, comment_quote)
         return TEMPLATE % {
                    'title': self.title,
                    'code': self.code,
diff -ruN paste-1.7.1.orig/paste/urlmap.py paste-1.7.1/paste/urlmap.py
--- paste-1.7.1.orig/paste/urlmap.py	2008-06-13 18:41:58.000000000 +0200
+++ paste-1.7.1/paste/urlmap.py	2010-06-25 23:48:18.223905611 +0200
@@ -7,6 +7,7 @@
 from UserDict import DictMixin
 import re
 import os
+import cgi
 from paste import httpexceptions
 
 __all__ = ['URLMap', 'PathProxyURLMap']
@@ -105,7 +106,7 @@
         extra += '\nHTTP_HOST: %r' % environ.get('HTTP_HOST')
         app = httpexceptions.HTTPNotFound(
             environ['PATH_INFO'],
-            comment=extra).wsgi_application
+            comment=cgi.escape(extra)).wsgi_application
         return app(environ, start_response)
 
     def normalize_url(self, url, trim=True):
diff -ruN paste-1.7.1.orig/paste/util/quoting.py paste-1.7.1/paste/util/quoting.py
--- paste-1.7.1.orig/paste/util/quoting.py	2008-06-13 18:41:58.000000000 +0200
+++ paste-1.7.1/paste/util/quoting.py	2010-06-25 23:48:18.223905611 +0200
@@ -72,6 +72,13 @@
     """
     return s
 
+_comment_quote_re = re.compile(r'\-\s*\>')
+def comment_quote(s):
+    """
+    Quote that makes sure text can't escape a comment
+    """
+    return _comment_quote_re.sub('-&gt', str(s))
+
 url_quote = urllib.quote
 url_unquote = urllib.unquote
 

Reply to: