Mercurial > moin > 1.9
view MoinMoin/action/fckdialog.py @ 6121:1563d6db198c
security: fix XSS in GUI editor's attachment dialogue CVE-2016-7146
author | Thomas Waldmann <tw AT waldmann-edv DOT de> |
---|---|
date | Fri, 28 Oct 2016 21:33:38 +0200 |
parents | 784aeb024774 |
children | 3bddf075fdbd |
line wrap: on
line source
# -*- coding: iso-8859-1 -*- """ MoinMoin - feed some FCKeditor dialogues @copyright: 2005-2006 Bastian Blank, Florian Festi, Thomas Waldmann @license: GNU GPL, see COPYING for details. """ from MoinMoin import config, wikiutil from MoinMoin.action.AttachFile import _get_files from MoinMoin.Page import Page import re ############################################################################## ### Macro dialog ############################################################################## def macro_dialog(request): help = get_macro_help(request) request.write( '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Insert Macro</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta content="noindex,nofollow" name="robots"> <script src="%s/applets/FCKeditor/editor/dialog/common/fck_dialog_common.js" type="text/javascript"></script> <script language="javascript"> var oEditor = window.parent.InnerDialogLoaded() ; var FCKLang = oEditor.FCKLang ; var FCKMacros = oEditor.FCKMacros ; window.onload = function () { // First of all, translate the dialog box texts oEditor.FCKLanguageManager.TranslatePage( document ) ; OnChange( "BR" ); // Show the "Ok" button. window.parent.SetOkButton( true ) ; } function Ok() { if ( document.getElementById('txtName').value.length == 0 ) { alert( FCKLang.MacroErrNoName ) ; return false ; } FCKMacros.Add( txtName.value ) ; return true ; } function OnChange( sMacro ) { // sMacro = GetE("txtName").value; oHelp = GetE("help"); for (var i=0; i<oHelp.childNodes.length; i++) { var oDiv = oHelp.childNodes[i]; if (oDiv.nodeType==1) { // oDiv.style.display = (GetAttribute(oDiv, "id", "")==sMacro) ? '' : 'none'; if (GetAttribute(oDiv, "id", "") == sMacro) { oDiv.style.display = '' ; // alert("enabled div id " + sMacro) ; } else { oDiv.style.display = 'none' ; } } } } </script> </head> <body scroll="no" style="OVERFLOW: hidden"> <table height="100%%" cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td> <table cellSpacing="0" cellPadding="0" align="center" border="0"> <tr> <td valign="top"> <span fckLang="MacroDlgName">Macro Name</span><br> <select id="txtName" size="10" onchange="OnChange(this.value);"> ''' % request.cfg.url_prefix_static) macros = [] for macro in macro_list(request): if macro == "BR": selected = ' selected="selected"' else: selected = '' if macro in help: macros.append('<option value="%s"%s>%s</option>' % (help[macro].group('prototype'), selected, macro)) else: macros.append('<option value="%s"%s>%s</option>' % (macro, selected, macro)) request.write('\n'.join(macros)) request.write(''' </select> </td> <td id="help">''') helptexts = [] for macro in macro_list(request): if macro in help: match = help[macro] prototype = match.group('prototype') helptext = match.group('help') else: prototype = macro helptext = "" helptexts.append( '''<div id="%s" style="DISPLAY: none"> <b><<%s>></b> <br/> <textarea style="color:#000000" cols="37" rows="10" disabled="disabled">%s</textarea> </div>''' % (prototype, prototype, helptext)) request.write(''.join(helptexts)) request.write(''' </td> </tr> </table> </td> </tr> </table> </body> </html> ''') def macro_list(request): from MoinMoin import macro macros = macro.getNames(request.cfg) macros.sort() return macros def get_macro_help(request): """ Read help texts from SystemPage('HelpOnMacros')""" helppage = wikiutil.getLocalizedPage(request, "HelpOnMacros") content = helppage.get_raw_body() macro_re = re.compile( r"\|\|(<.*?>)?\{\{\{" + r"<<(?P<prototype>(?P<macro>\w*).*)>>" + r"\}\}\}\s*\|\|" + r"[^|]*\|\|[^|]*\|\|<[^>]*>" + r"\s*(?P<help>.*?)\s*\|\|\s*(?P<example>.*?)\s*(<<[^>]*>>)*\s*\|\|$", re.U|re.M) help = {} for match in macro_re.finditer(content): help[match.group('macro')] = match return help ############################################################################## ### Link dialog ############################################################################## def page_list(request): from MoinMoin import search name = request.values.get("pagename", "") if name: searchresult = search.searchPages(request, 't:"%s"' % name) pages = [p.page_name for p in searchresult.hits] else: pages = [name] request.write( '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Insert Page Link</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta content="noindex,nofollow" name="robots"> </head> <body scroll="no" style="OVERFLOW: hidden"> <table height="100%%" cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td> <table cellSpacing="0" cellPadding="0" align="center" border="0"> <tr> <td> <span fckLang="PageDlgName">Page name</span><br> <select id="txtName" size="1"> %s </select> </td> </tr> </table> </td> </tr> </table> </body> </html> ''' % "".join(["<option>%s</option>\n" % p for p in pages])) def link_dialog(request): # list of wiki pages name = request.values.get("pagename", "") if name: from MoinMoin import search # XXX error handling! searchresult = search.searchPages(request, 't:"%s"' % name) pages = [p.page_name for p in searchresult.hits] pages.sort() pages[0:0] = [name] page_list = ''' <tr> <td colspan=2> <select id="sctPagename" size="1" onchange="OnChangePagename(this.value);"> %s </select> <td> </tr> ''' % "\n".join(['<option value="%s">%s</option>' % (page, page) for page in pages]) else: page_list = "" # list of interwiki names interwiki_list = wikiutil.load_wikimap(request) interwiki = interwiki_list.keys() interwiki.sort() iwpreferred = request.cfg.interwiki_preferred[:] if not iwpreferred or iwpreferred and iwpreferred[-1] is not None: resultlist = iwpreferred for iw in interwiki: if not iw in iwpreferred: resultlist.append(iw) else: resultlist = iwpreferred[:-1] interwiki = "\n".join( ['<option value="%s">%s</option>' % (key, key) for key in resultlist]) # wiki url url_prefix_static = request.cfg.url_prefix_static scriptname = request.script_root + '/' action = scriptname basepage = request.page.page_name request.write(u''' <!-- * FCKeditor - The text editor for internet * Copyright (C) 2003-2004 Frederico Caldeira Knabben * * Licensed under the terms of the GNU Lesser General Public License: * http://www.opensource.org/licenses/lgpl-license.php * * For further information visit: * http://www.fckeditor.net/ * * File Name: fck_link.html * Link dialog window. * * Version: 2.0 FC (Preview) * Modified: 2005-02-18 23:55:22 * * File Authors: * Frederico Caldeira Knabben (fredck@fckeditor.net) --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <meta name="robots" content="index,nofollow"> <html> <head> <title>Link Properties</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="robots" content="noindex,nofollow" /> <script src="%(url_prefix_static)s/applets/FCKeditor/editor/dialog/common/fck_dialog_common.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinlink/fck_link.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinurllib.js" type="text/javascript"></script> </head> <body scroll="no" style="OVERFLOW: hidden"> <div id="divInfo" style="DISPLAY: none"> <span fckLang="DlgLnkType">Link Type</span><br /> <select id="cmbLinkType" onchange="SetLinkType(this.value);"> <option value="wiki" selected="selected">WikiPage</option> <option value="interwiki">Interwiki</option> <option value="url" fckLang="DlgLnkTypeURL">URL</option> </select> <br /> <br /> <div id="divLinkTypeWiki"> <table height="100%%" cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td> <form action=%(action)s method="GET"> <input type="hidden" name="action" value="fckdialog"> <input type="hidden" name="dialog" value="link"> <input type="hidden" id="basepage" name="basepage" value="%(basepage)s"> <table cellSpacing="0" cellPadding="0" align="center" border="0"> <tr> <td> <span fckLang="PageDlgName">Page Name</span><br> <input id="txtPagename" name="pagename" size="30" value="%(name)s"> </td> <td valign="bottom"> <input id=btnSearchpage type="submit" value="Search"> </td> </tr> %(page_list)s </table> </form> </td> </tr> </table> </div> <div id="divLinkTypeInterwiki"> <table height="100%%" cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td> <table cellSpacing="0" cellPadding="0" align="center" border="0"> <tr> <td> <span fckLang="WikiDlgName">Wiki:PageName</span><br> <select id="sctInterwiki" size="1"> %(interwiki)s </select>: <input id="txtInterwikipagename"></input> </td> </tr> </table> </td> </tr> </table> </div> <div id="divLinkTypeUrl"> <table cellspacing="0" cellpadding="0" width="100%%" border="0"> <tr> <td nowrap="nowrap"> <span fckLang="DlgLnkProto">Protocol</span><br /> <select id="cmbLinkProtocol"> <option value="http://" selected="selected">http://</option> <option value="https://">https://</option> <option value="ftp://">ftp://</option> <option value="file://">file://</option> <option value="news://">news://</option> <option value="mailto:">mailto:</option> <option value="" fckLang="DlgLnkProtoOther"><other></option> </select> </td> <td nowrap="nowrap"> </td> <td nowrap="nowrap" width="100%%"> <span fckLang="DlgLnkURL">URL</span><br /> <input id="txtUrl" style="WIDTH: 100%%" type="text" onkeyup="OnUrlChange();" onchange="OnUrlChange();" /> </td> </tr> </table> <br /> </div> </div> </body> </html> ''' % locals()) def attachment_dialog(request): """ Attachment dialog for GUI editor. """ """ Features: This dialog can... """ """ - list attachments in a drop down list """ """ - list attachments also for a different page than the current one """ """ - create new attachment """ _ = request.getText url_prefix_static = request.cfg.url_prefix_static # wiki url action = request.script_root + "/" # The following code lines implement the feature "list attachments for a different page". # Meaning of the variables: # - requestedPagename : Name of the page where attachments shall be listed from. # - attachmentsPagename : Name of the page where the attachments where retrieved from. # - destinationPagename : Name of the page where attachment will be placed on. requestedPagename = wikiutil.escape(request.values.get("requestedPagename", ""), quote=True) destinationPagename = wikiutil.escape(request.values.get("destinationPagename", request.page.page_name), quote=True) attachmentsPagename = requestedPagename or wikiutil.escape(request.page.page_name) attachments = _get_files(request, attachmentsPagename) attachments.sort() attachmentList = ''' <select id="sctAttachments" size="10" style="width:100%%;visibility:hidden;" onchange="OnAttachmentListChange();"> %s </select> ''' % "\n".join(['<option value="%s">%s</option>' % (wikiutil.escape(attachment, quote=True), wikiutil.escape(attachment, quote=True)) for attachment in attachments]) # Translation of dialog texts. langAttachmentLocation = _("Attachment location") langPagename = _("Page name") langAttachmentname = _("Attachment name") langListAttachmentsButton = _("Refresh attachment list") langAttachmentList = _("List of attachments") if len(attachmentsPagename) > 50: shortenedPagename = "%s ... %s" % (attachmentsPagename[0:25], attachmentsPagename[-25:]) else: shortenedPagename = attachmentsPagename langAvailableAttachments = "%s: %s" % (_("Available attachments for page"), shortenedPagename) request.write(''' <!-- * FCKeditor - The text editor for internet * Copyright (C) 2003-2004 Frederico Caldeira Knabben * * Licensed under the terms of the GNU Lesser General Public License: * http://www.opensource.org/licenses/lgpl-license.php * * For further information visit: * http://www.fckeditor.net/ * * File Name: fck_attachment.html * Attachment dialog window. * * Version: 2.0 FC (Preview) * Modified: 2005-02-18 23:55:22 * * File Authors: * Frederico Caldeira Knabben (fredck@fckeditor.net) --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <meta name="robots" content="index,nofollow"> <html> <head> <title>Attachment Properties</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="robots" content="noindex,nofollow" /> <script src="%(url_prefix_static)s/applets/FCKeditor/editor/dialog/common/fck_dialog_common.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinattachment/fck_attachment.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinurllib.js" type="text/javascript"></script> </head> <body scroll="no" style="OVERFLOW: hidden"> <form id="DlgAttachmentForm" name="DlgAttachmentForm" action=%(action)s method="GET"> <input type="hidden" name="action" value="fckdialog"> <input type="hidden" name="dialog" value="attachment"> <input type="hidden" id="requestedPagename" name="requestedPagename" value="%(requestedPagename)s"> <input type="hidden" id="attachmentsPagename" name="attachmentsPagename" value="%(attachmentsPagename)s"> <input type="hidden" id="destinationPagename" name="destinationPagename" value="%(destinationPagename)s"> <div id="divInfo" style="valign=top;"> <div id="divLinkTypeAttachment"> <fieldset> <legend>%(langAttachmentLocation)s</legend> <table cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td valign="bottom" style="width:90%%" style="padding-bottom:10px"> <span>%(langPagename)s</span><br> </td> </tr> <tr> <td valign="bottom" style="width:100%%" style="padding-bottom:10px;padding-right:10px;"> <input id="txtPagename" type="text" onkeyup="OnPagenameChange();" onchange="OnPagenameChange();" style="width:98%%"> </td> </tr> <tr> <td valign="bottom" style="width:90%%" style="padding-bottom:10px;"> <span>%(langAttachmentname)s</span><br> </td> </tr> <tr valign="bottom"> <td valign="bottom" style="width:100%%" style="padding-bottom:10px;padding-right:10px;"> <input id="txtAttachmentname" type="text" onkeyup="OnAttachmentnameChange();" onchange="OnPagenameChange();" style="width:98%%"><br> </td> </tr> </table> </fieldset> <fieldset> <legend>%(langAvailableAttachments)s</legend> <table cellSpacing="0" cellPadding="0" width="100%%" border="0"> <tr> <td valign="bottom" style="width:100%%" style="padding-bottom:10px"> <input id="btnListAttachments" type="submit" value="%(langListAttachmentsButton)s"> </td> </tr> <tr> <td valign="top" style="padding-top:10px"> <label for="sctAttachments">%(langAttachmentList)s</label><br> %(attachmentList)s </td> </tr> </table> </fieldset> </div> </div> </form> </body> </html> ''' % locals()) ############################################################################## ### Image dialog ############################################################################## def image_dialog(request): url_prefix_static = request.cfg.url_prefix_static request.write(''' <!-- * FCKeditor - The text editor for internet * Copyright (C) 2003-2004 Frederico Caldeira Knabben * * Licensed under the terms of the GNU Lesser General Public License: * http://www.opensource.org/licenses/lgpl-license.php * * For further information visit: * http://www.fckeditor.net/ * * File Authors: * Frederico Caldeira Knabben (fredck@fckeditor.net) * Florian Festi --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Link Properties</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="robots" content="noindex,nofollow" /> <script src="%(url_prefix_static)s/applets/FCKeditor/editor/dialog/common/fck_dialog_common.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinimage/fck_image.js" type="text/javascript"></script> <script src="%(url_prefix_static)s/applets/moinFCKplugins/moinurllib.js" type="text/javascript"></script> </head> <body scroll="no" style="OVERFLOW: hidden"> <table cellspacing="0" cellpadding="0" width="100%%" border="0"> <tr> <td nowrap="nowrap"> <span fckLang="DlgLnkProto">Protocol</span><br /> <select id="cmbLinkProtocol" onchange="OnProtocolChange();"> <option value="attachment:" selected="selected">attachment:</option> <option value="http://">http://</option> <option value="https://">https://</option> <!-- crashes often: <option value="drawing:">drawing:</option> --> <option value="" fckLang="DlgLnkProtoOther"><other></option> </select> </td> <td nowrap="nowrap"> </td> <td nowrap="nowrap" width="100%%"> <span fckLang="DlgLnkURL">URL or File Name (attachment:)</span><br /> <input id="txtUrl" style="WIDTH: 100%%" type="text" onkeyup="OnUrlChange();" onchange="OnUrlChange();" /> </td> </tr> <tr> <td colspan=2> <div id="divChkLink"> <input id="chkLink" type="checkbox"> Link to </div> </td> </table> </body> </html> ''' % locals()) ############################################################################# ### Main ############################################################################# def execute(pagename, request): dialog = request.values.get("dialog", "") if dialog == "macro": macro_dialog(request) elif dialog == "macrolist": macro_list(request) elif dialog == "pagelist": page_list(request) elif dialog == "link": link_dialog(request) elif dialog == "attachment": attachment_dialog(request) elif dialog == 'image': image_dialog(request) else: from MoinMoin.Page import Page request.theme.add_msg("Dialog unknown!", "error") Page(request, pagename).send_page()