Skip to content

Commit

Permalink
XWIKI-20261: Improved escaping of AdminFieldsDisplaySheet
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelleduc committed Nov 29, 2022
1 parent 86ef362 commit 04aa06d
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@
<artifactId>bootstrap-select</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Test dependencies. -->
<dependency>
<groupId>org.xwiki.platform</groupId>
<artifactId>xwiki-platform-test-page</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xwiki.commons</groupId>
<artifactId>xwiki-commons-script</artifactId>
<version>${commons.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,14 @@
#set($configClassName = 'XWiki.XWikiPreferences')
#set($formId = $section.toLowerCase())
#end
&lt;form id="$formId" method="post" action="$xwiki.getURL($configDoc, 'saveandcontinue')" onsubmit="cancelCancelEdit()" class="xform"&gt;
&lt;form id="$escapetool.xml($formId)" method="post"
action="$escapetool.xml($xwiki.getURL($configDoc, 'saveandcontinue'))"
onsubmit="cancelCancelEdit()"
class="xform"&gt;
#set($obj = $configDoc.getObject($configClassName))
#foreach ($entry in $params.entrySet())
#set ($fields = $entry.value)
&lt;fieldset class="$entry.key"&gt;
&lt;fieldset class="$escapetool.xml($entry.key)"&gt;
## If there is only one section, don't display the legend
#if ($params.size() &gt; 1)
&lt;legend&gt;$services.localization.render("admin.$entry.key")&lt;/legend&gt;
Expand All @@ -144,7 +147,7 @@
&lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
&lt;input type="hidden" name="xcontinue" value="$xwiki.getURL($currentDoc, 'admin', "editor=${escapetool.url(${editor})}&amp;amp;section=${escapetool.url(${section})}&amp;amp;space=${escapetool.url(${currentSpace})}")" /&gt;
&lt;input type="hidden" name="xredirect" value="$xwiki.getURL($currentDoc, 'admin', "editor=${escapetool.url(${editor})}&amp;amp;section=${escapetool.url(${section})}&amp;amp;space=${escapetool.url(${currentSpace})}")" /&gt;
&lt;input type="hidden" name="classname" value="$configClassName" /&gt;
&lt;input type="hidden" name="classname" value="$escapetool.xml($configClassName)" /&gt;
&lt;/div&gt;
&lt;div class="bottombuttons"&gt;
&lt;p class="admin-buttons"&gt;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.administration;

import java.util.Map;

import javax.script.ScriptContext;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration;
import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource;
import org.xwiki.rendering.internal.macro.DefaultMacroCategoryManager;
import org.xwiki.rendering.internal.syntax.SyntaxConverter;
import org.xwiki.rendering.internal.transformation.macro.DefaultMacroTransformationConfiguration;
import org.xwiki.rendering.script.RenderingScriptService;
import org.xwiki.script.ScriptContextManager;
import org.xwiki.test.annotation.ComponentList;
import org.xwiki.test.page.HTML50ComponentList;
import org.xwiki.test.page.PageTest;
import org.xwiki.test.page.TestNoScriptMacro;
import org.xwiki.test.page.XWikiSyntax21ComponentList;
import org.xwiki.xml.internal.html.filter.ControlCharactersFilter;

import static java.util.Collections.emptyList;
import static java.util.Collections.singletonMap;
import static javax.script.ScriptContext.ENGINE_SCOPE;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* Page test of {@code XWiki.AdminFieldsDisplaySheet}.
*
* @version $Id$
* @since 15.0RC1
* @since 14.10.1
* @since 14.4.8
* @since 13.10.11
*/
@HTML50ComponentList
@XWikiSyntax21ComponentList
@ComponentList({
TestNoScriptMacro.class,
DefaultExtendedRenderingConfiguration.class,
RenderingConfigClassDocumentConfigurationSource.class,
// Start RenderingScriptService
RenderingScriptService.class,
DefaultExtendedRenderingConfiguration.class,
RenderingConfigClassDocumentConfigurationSource.class,
SyntaxConverter.class,
DefaultMacroCategoryManager.class,
DefaultMacroTransformationConfiguration.class,
// End RenderingScriptService
ControlCharactersFilter.class
})
class AdminFieldsDisplaySheetPageTest extends PageTest
{
private ScriptContext scriptContext;

@BeforeEach
void setUp() throws Exception
{
this.scriptContext =
this.oldcore.getMocker().<ScriptContextManager>getInstance(ScriptContextManager.class).getScriptContext();
}

@Test
void escaping() throws Exception
{
String paramsInput = "\"/><script>console.log('params');</script>{{/html}}{{noscript/}}";
String sectionInput = "\"/><strong>console.log('section');</script>{{/html}}{{noscript/}}";
String paramClassInput = "\"/><script>console.log('paramClass');</script>{{/html}}{{noscript/}}";
Map<Object, Object> params = singletonMap(paramsInput, emptyList());
DocumentReference otherDocumentReference = new DocumentReference("xwiki", "Space", "Page");
com.xpn.xwiki.api.Document otherDocument =
new com.xpn.xwiki.api.Document(this.xwiki.getDocument(otherDocumentReference, this.context), this.context);

this.scriptContext.setAttribute("section", sectionInput, ENGINE_SCOPE);
this.scriptContext.setAttribute("paramDoc", otherDocument, ENGINE_SCOPE);
this.scriptContext.setAttribute("params", params, ENGINE_SCOPE);
this.scriptContext.setAttribute("paramClass", paramClassInput, ENGINE_SCOPE);

Document document = renderHTMLPage(new DocumentReference("xwiki", "XWiki", "AdminFieldsDisplaySheet"));

Element form = document.selectFirst("form");
assertEquals(String.format("%s_%s", sectionInput, paramClassInput), form.attr("id"));
assertEquals("/xwiki/bin/saveandcontinue/Space/Page", form.attr("action"));
Element fieldset = form.selectFirst("fieldset");
assertEquals(paramsInput, fieldset.attr("class"));
assertEquals(paramClassInput, document.selectFirst(".hidden input[name='classname']").val());
}
}

0 comments on commit 04aa06d

Please sign in to comment.