changeset 3895:37306fba2189

Fixing security issues related to MoinMoinBugs/1.9.2UnescapedInputForThemeAddMsg (possible XSS)
author Eugene Syromyatnikov <evgsyr@gmail.com>
date Fri, 04 Jun 2010 00:13:24 +0400
parents 0d76fbaa3cd9
children f8871116c6b3
files MoinMoin/Page.py MoinMoin/PageEditor.py MoinMoin/PageGraphicalEditor.py MoinMoin/action/CopyPage.py MoinMoin/action/LikePages.py MoinMoin/action/Load.py MoinMoin/action/RenamePage.py MoinMoin/action/backup.py MoinMoin/action/chart.py MoinMoin/action/login.py MoinMoin/action/newaccount.py MoinMoin/action/recoverpass.py MoinMoin/action/userprofile.py
diffstat 13 files changed, 29 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/Page.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/Page.py	Fri Jun 04 00:13:24 2010 +0400
@@ -1053,8 +1053,8 @@
                 if 'highlight' in request.form:
                     del request.form['highlight']
                 request.theme.add_msg(_('Invalid highlighting regular expression "%(regex)s": %(error)s') % {
-                                          'regex': self.hilite_re,
-                                          'error': str(err),
+                                          'regex': wikiutil.escape(self.hilite_re),
+                                          'error': wikiutil.escape(str(err)),
                                       }, "warning")
                 self.hilite_re = None
 
@@ -1111,7 +1111,7 @@
                     request.theme.add_msg("<strong>%s</strong><br>" % (
                         _('Revision %(rev)d as of %(date)s') % {
                             'rev': self.rev,
-                            'date': self.mtime_printable(request)
+                            'date': wikiutil.escape(self.mtime_printable(request))
                         }), "info")
 
                 # This redirect message is very annoying.
--- a/MoinMoin/PageEditor.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/PageEditor.py	Fri Jun 04 00:13:24 2010 +0400
@@ -278,14 +278,15 @@
         elif 'template' in form:
             # If the page does not exist, we try to get the content from the template parameter.
             template_page = wikiutil.unquoteWikiname(form['template'][0])
+            template_page_escaped = wikiutil.escape(template_page)
             if request.user.may.read(template_page):
                 raw_body = Page(request, template_page).get_raw_body()
                 if raw_body:
-                    request.theme.add_msg(_("[Content of new page loaded from %s]") % (template_page, ), 'info')
+                    request.theme.add_msg(_("[Content of new page loaded from %s]") % (template_page_escaped, ), 'info')
                 else:
-                    request.theme.add_msg(_("[Template %s not found]") % (template_page, ), 'warning')
+                    request.theme.add_msg(_("[Template %s not found]") % (template_page_escaped, ), 'warning')
             else:
-                request.theme.add_msg(_("[You may not read %s]") % (template_page, ), 'error')
+                request.theme.add_msg(_("[You may not read %s]") % (template_page_escaped, ), 'error')
 
         # Make backup on previews - but not for new empty pages
         if not use_draft and preview and raw_body:
--- a/MoinMoin/PageGraphicalEditor.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/PageGraphicalEditor.py	Fri Jun 04 00:13:24 2010 +0400
@@ -171,14 +171,15 @@
         elif 'template' in form:
             # If the page does not exist, we try to get the content from the template parameter.
             template_page = wikiutil.unquoteWikiname(form['template'][0])
+            template_page_escaped = wikiutil.escape(template_page)
             if request.user.may.read(template_page):
                 raw_body = Page(request, template_page).get_raw_body()
                 if raw_body:
-                    request.write(_("[Content of new page loaded from %s]") % (template_page, ), '<br>')
+                    request.write(_("[Content of new page loaded from %s]") % (template_page_escaped, ), '<br>')
                 else:
-                    request.write(_("[Template %s not found]") % (template_page, ), '<br>')
+                    request.write(_("[Template %s not found]") % (template_page_escaped, ), '<br>')
             else:
-                request.write(_("[You may not read %s]") % (template_page, ), '<br>')
+                request.write(_("[You may not read %s]") % (template_page_escaped, ), '<br>')
 
         # Make backup on previews - but not for new empty pages
         if not use_draft and preview and raw_body:
--- a/MoinMoin/action/CopyPage.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/CopyPage.py	Fri Jun 04 00:13:24 2010 +0400
@@ -87,7 +87,7 @@
     def get_form_html(self, buttons_html):
         _ = self._
         if self.users_subpages:
-            subpages = ' '.join(self.users_subpages)
+            subpages = ' '.join([wikiutil.escape(page) for page in self.users_subpages])
 
             d = {
                 'textcha': TextCha(self.request).render(),
--- a/MoinMoin/action/LikePages.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/LikePages.py	Fri Jun 04 00:13:24 2010 +0400
@@ -24,19 +24,19 @@
 
     # Error?
     if isinstance(matches, (str, unicode)):
-        request.theme.add_msg(matches, "info")
+        request.theme.add_msg(wikiutil.escape(matches), "info")
         Page(request, pagename).send_page()
         return
 
     # No matches
     if not matches:
-        request.theme.add_msg(_('No pages like "%s"!') % (pagename, ), "error")
+        request.theme.add_msg(_('No pages like "%s"!') % (wikiutil.escape(pagename), ), "error")
         Page(request, pagename).send_page()
         return
 
     # One match - display it
     if len(matches) == 1:
-        request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (pagename, ), "info")
+        request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (wikiutil.escape(pagename), ), "info")
         Page(request, matches.keys()[0]).send_page()
         return
 
--- a/MoinMoin/action/Load.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/Load.py	Fri Jun 04 00:13:24 2010 +0400
@@ -108,7 +108,7 @@
     'upload_label_file': _('File to load page content from'),
     'upload_label_comment': _('Comment'),
     'upload_label_rename': _('Page Name'),
-    'pagename': self.pagename,
+    'pagename': wikiutil.escape(self.pagename, quote=1),
     'buttons_html': buttons_html,
     'action_name': self.form_trigger,
     'textcha': TextCha(self.request).render(),
--- a/MoinMoin/action/RenamePage.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/RenamePage.py	Fri Jun 04 00:13:24 2010 +0400
@@ -80,7 +80,7 @@
     def get_form_html(self, buttons_html):
         _ = self._
         if self.subpages:
-            subpages = ' '.join(self.subpages)
+            subpages = ' '.join([wikiutil.escape(page) for page in self.subpages])
 
             d = {
                 'subpage': subpages,
--- a/MoinMoin/action/backup.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/backup.py	Fri Jun 04 00:13:24 2010 +0400
@@ -114,7 +114,11 @@
     request.theme.send_footer(pagename)
     request.theme.send_closing_html()
 
+# NOTE: consider using ActionBase.render_msg instead of this function.
 def sendMsg(request, pagename, msg, msgtype):
+    """
+    @param msg: Message to show. Should be escaped.
+    """
     from MoinMoin import Page
     request.theme.add_msg(msg, msgtype)
     return Page.Page(request, pagename).send_page()
@@ -140,4 +144,4 @@
         sendBackupForm(request, pagename)
     else:
         return sendMsg(request, pagename,
-                       msg=_('Unknown backup subaction: %s.') % dowhat, msgtype="error")
+                       msg=_('Unknown backup subaction: %s.') % wikiutil.escape(dowhat), msgtype="error")
--- a/MoinMoin/action/chart.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/chart.py	Fri Jun 04 00:13:24 2010 +0400
@@ -6,6 +6,7 @@
                 2006 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
+from MoinMoin import wikiutil
 from MoinMoin.util import pysupport
 
 def execute(pagename, request):
@@ -27,7 +28,7 @@
     try:
         func = pysupport.importName("MoinMoin.stats.%s" % chart_type, 'draw')
     except (ImportError, AttributeError):
-        request.theme.add_msg(_('Bad chart type "%s"!') % chart_type, "error")
+        request.theme.add_msg(_('Bad chart type "%s"!') % wikiutil.escape(chart_type), "error")
         return request.page.send_page()
 
     func(pagename, request)
--- a/MoinMoin/action/login.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/login.py	Fri Jun 04 00:13:24 2010 +0400
@@ -68,7 +68,7 @@
             if hasattr(request, '_login_messages'):
                 for msg in request._login_messages:
                     error.append('<p>')
-                    error.append(msg)
+                    error.append(wikiutil.escape(msg))
                 error = ''.join(error)
             request.theme.add_msg(error, "error")
             return self.page.send_page()
--- a/MoinMoin/action/newaccount.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/newaccount.py	Fri Jun 04 00:13:24 2010 +0400
@@ -61,7 +61,7 @@
     if pw_checker:
         pw_error = pw_checker(theuser.name, password)
         if pw_error:
-            return _("Password not acceptable: %s") % pw_error
+            return _("Password not acceptable: %s") % wikiutil.escape(pw_error)
 
     # Encode password
     if password and not password.startswith('{SHA}'):
@@ -69,7 +69,7 @@
             theuser.enc_password = user.encodePassword(password)
         except UnicodeError, err:
             # Should never happen
-            return "Can't encode password: %s" % str(err)
+            return "Can't encode password: %s" % wikiutil.escape(str(err))
 
     # try to get the email, for new users it is required
     email = wikiutil.clean_input(form.get('email', [''])[0])
--- a/MoinMoin/action/recoverpass.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/recoverpass.py	Fri Jun 04 00:13:24 2010 +0400
@@ -175,7 +175,7 @@
             if pw_checker:
                 pw_error = pw_checker(name, newpass)
                 if pw_error:
-                    msg = _("Password not acceptable: %s") % pw_error
+                    msg = _("Password not acceptable: %s") % wikiutil.escape(pw_error)
             if not pw_error:
                 u = user.User(request, user.getUserId(request, name))
                 if u and u.valid and u.apply_recovery_token(token, newpass):
--- a/MoinMoin/action/userprofile.py	Fri Jun 04 00:08:29 2010 +0400
+++ b/MoinMoin/action/userprofile.py	Fri Jun 04 00:13:24 2010 +0400
@@ -28,7 +28,7 @@
         oldval = getattr(theuser, key)
         setattr(theuser, key, val)
         theuser.save()
-        request.theme.add_msg('%s.%s: %s -> %s' % (user_name, key, oldval, val), "info")
+        request.theme.add_msg('%s.%s: %s -> %s' % tuple([wikiutil.escape(s) for s in [user_name, key, oldval, val]]), "info")
 
     Page(request, pagename).send_page()