Skip to content

Commit f1e3108

Browse files
committed
XWIKI-20261: Improved escaping of AdminFieldsDisplaySheet
1 parent 01b982b commit f1e3108

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

Diff for: xwiki-platform-core/xwiki-platform-administration/xwiki-platform-administration-ui/pom.xml

+21
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,27 @@
9191
<artifactId>bootstrap-select</artifactId>
9292
<scope>runtime</scope>
9393
</dependency>
94+
<!-- Test dependencies. -->
95+
<dependency>
96+
<groupId>org.xwiki.platform</groupId>
97+
<artifactId>xwiki-platform-test-page</artifactId>
98+
<version>${project.version}</version>
99+
<scope>test</scope>
100+
</dependency>
101+
<dependency>
102+
<groupId>org.xwiki.commons</groupId>
103+
<artifactId>xwiki-commons-script</artifactId>
104+
<version>${commons.version}</version>
105+
<scope>test</scope>
106+
</dependency>
107+
<!-- Provides the component list for RenderingScriptService. -->
108+
<dependency>
109+
<groupId>org.xwiki.platform</groupId>
110+
<artifactId>xwiki-platform-rendering-xwiki</artifactId>
111+
<version>${project.version}</version>
112+
<type>test-jar</type>
113+
<scope>test</scope>
114+
</dependency>
94115
</dependencies>
95116
<build>
96117
<plugins>

Diff for: xwiki-platform-core/xwiki-platform-administration/xwiki-platform-administration-ui/src/main/resources/XWiki/AdminFieldsDisplaySheet.xml

+6-3
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,14 @@
116116
#set($configClassName = 'XWiki.XWikiPreferences')
117117
#set($formId = $section.toLowerCase())
118118
#end
119-
&lt;form id="$formId" method="post" action="$xwiki.getURL($configDoc, 'saveandcontinue')" onsubmit="cancelCancelEdit()" class="xform"&gt;
119+
&lt;form id="$escapetool.xml($formId)" method="post"
120+
action="$escapetool.xml($xwiki.getURL($configDoc, 'saveandcontinue'))"
121+
onsubmit="cancelCancelEdit()"
122+
class="xform"&gt;
120123
#set($obj = $configDoc.getObject($configClassName))
121124
#foreach ($entry in $params.entrySet())
122125
#set ($fields = $entry.value)
123-
&lt;fieldset class="$entry.key"&gt;
126+
&lt;fieldset class="$escapetool.xml($entry.key)"&gt;
124127
## If there is only one section, don't display the legend
125128
#if ($params.size() &gt; 1)
126129
&lt;legend&gt;$services.localization.render("admin.$entry.key")&lt;/legend&gt;
@@ -145,7 +148,7 @@
145148
&lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
146149
&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;
147150
&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;
148-
&lt;input type="hidden" name="classname" value="$configClassName" /&gt;
151+
&lt;input type="hidden" name="classname" value="$escapetool.xml($configClassName)" /&gt;
149152
#if ("$!objectPolicy" != '')
150153
&lt;input type="hidden" name="objectPolicy" value="$escapetool.xml($objectPolicy)" /&gt;
151154
#end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* See the NOTICE file distributed with this work for additional
3+
* information regarding copyright ownership.
4+
*
5+
* This is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU Lesser General Public License as
7+
* published by the Free Software Foundation; either version 2.1 of
8+
* the License, or (at your option) any later version.
9+
*
10+
* This software is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this software; if not, write to the Free
17+
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18+
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19+
*/
20+
package org.xwiki.administration;
21+
22+
import java.util.Map;
23+
24+
import javax.script.ScriptContext;
25+
26+
import org.jsoup.nodes.Document;
27+
import org.jsoup.nodes.Element;
28+
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.Test;
30+
import org.xwiki.model.reference.DocumentReference;
31+
import org.xwiki.rendering.RenderingScriptServiceComponentList;
32+
import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration;
33+
import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource;
34+
import org.xwiki.script.ScriptContextManager;
35+
import org.xwiki.test.annotation.ComponentList;
36+
import org.xwiki.test.page.HTML50ComponentList;
37+
import org.xwiki.test.page.PageTest;
38+
import org.xwiki.test.page.TestNoScriptMacro;
39+
import org.xwiki.test.page.XWikiSyntax21ComponentList;
40+
41+
import static java.util.Collections.emptyList;
42+
import static java.util.Collections.singletonMap;
43+
import static javax.script.ScriptContext.ENGINE_SCOPE;
44+
import static org.junit.jupiter.api.Assertions.assertEquals;
45+
46+
/**
47+
* Page test of {@code XWiki.AdminFieldsDisplaySheet}.
48+
*
49+
* @version $Id$
50+
* @since 15.0RC1
51+
* @since 14.10.1
52+
* @since 14.4.8
53+
* @since 13.10.11
54+
*/
55+
@HTML50ComponentList
56+
@XWikiSyntax21ComponentList
57+
@RenderingScriptServiceComponentList
58+
@ComponentList({
59+
TestNoScriptMacro.class,
60+
DefaultExtendedRenderingConfiguration.class,
61+
RenderingConfigClassDocumentConfigurationSource.class
62+
})
63+
class AdminFieldsDisplaySheetPageTest extends PageTest
64+
{
65+
private ScriptContext scriptContext;
66+
67+
@BeforeEach
68+
void setUp() throws Exception
69+
{
70+
this.scriptContext =
71+
this.oldcore.getMocker().<ScriptContextManager>getInstance(ScriptContextManager.class).getScriptContext();
72+
}
73+
74+
@Test
75+
void escaping() throws Exception
76+
{
77+
String paramsInput = "\"/><script>console.log('params');</script>{{/html}}{{noscript/}}";
78+
String sectionInput = "\"/><strong>console.log('section');</script>{{/html}}{{noscript/}}";
79+
String paramClassInput = "\"/><script>console.log('paramClass');</script>{{/html}}{{noscript/}}";
80+
Map<Object, Object> params = singletonMap(paramsInput, emptyList());
81+
DocumentReference otherDocumentReference = new DocumentReference("xwiki", "Space", "Page");
82+
com.xpn.xwiki.api.Document otherDocument =
83+
new com.xpn.xwiki.api.Document(this.xwiki.getDocument(otherDocumentReference, this.context), this.context);
84+
85+
this.scriptContext.setAttribute("section", sectionInput, ENGINE_SCOPE);
86+
this.scriptContext.setAttribute("paramDoc", otherDocument, ENGINE_SCOPE);
87+
this.scriptContext.setAttribute("params", params, ENGINE_SCOPE);
88+
this.scriptContext.setAttribute("paramClass", paramClassInput, ENGINE_SCOPE);
89+
90+
Document document = renderHTMLPage(new DocumentReference("xwiki", "XWiki", "AdminFieldsDisplaySheet"));
91+
92+
Element form = document.selectFirst("form");
93+
assertEquals(String.format("%s_%s", sectionInput, paramClassInput), form.attr("id"));
94+
assertEquals("/xwiki/bin/saveandcontinue/Space/Page", form.attr("action"));
95+
Element fieldset = form.selectFirst("fieldset");
96+
assertEquals(paramsInput, fieldset.attr("class"));
97+
assertEquals(paramClassInput, document.selectFirst(".hidden input[name='classname']").val());
98+
}
99+
}

0 commit comments

Comments
 (0)