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('->', 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('->', str(s))
+
url_quote = urllib.quote
url_unquote = urllib.unquote
Reply to: