You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by al...@apache.org on 2026/08/23 16:17:27 UTC

(jspwiki) branch bug/JSPWIKI-1292 created (now 50b89b9fe)

This is an automated email from the ASF dual-hosted git repository.

spyhunter99 pushed a change to branch bug/JSPWIKI-1292
in repository https://gitbox.apache.org/repos/asf/jspwiki.git


      at 50b89b9fe JSPWIKI-1292 see jira for details

This branch includes the following new commits:

     new 50b89b9fe JSPWIKI-1292 see jira for details

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(jspwiki) 01/01: JSPWIKI-1292 see jira for details

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spyhunter99 pushed a commit to branch bug/JSPWIKI-1292
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 50b89b9fe8c3901b132fef99f521c8b6e0817cd1
Author: Alex O'Ree <al...@apache.org>
AuthorDate: Sun Aug 23 12:17:12 2026 -0400

    JSPWIKI-1292 see jira for details
---
 .../apache/wiki/parser/JSPWikiMarkupParser.java    |  4 ++--
 .../java/org/apache/wiki/parser/PluginContent.java |  7 ++++--
 .../wiki/render/WysiwygEditingRendererTest.java    | 26 ++++++++++++++++++++++
 .../main/webapp/templates/210/editors/CKeditor.jsp |  2 +-
 .../main/webapp/templates/210/editors/TinyMCE.jsp  |  2 +-
 .../webapp/templates/default/editors/CKeditor.jsp  |  2 +-
 .../webapp/templates/default/editors/TinyMCE.jsp   |  2 +-
 .../webapp/templates/default/editors/wysiwyg.jsp   |  2 +-
 8 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
index 8f901f64a..4c600786e 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java
@@ -787,7 +787,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
 
     private Element handleAccessRule( String ruleLine ) {
         if( m_wysiwygEditorMode ) {
-            m_currentElement.addContent( "[" + ruleLine + "]" );
+            m_currentElement.addContent( "[" + TextUtil.escapeHTMLEntities( ruleLine ) + "]" );
         }
         if( !m_parseAccessRules ) {
             return m_currentElement;
@@ -821,7 +821,7 @@ public class JSPWikiMarkupParser extends MarkupParser {
      */
     private Element handleMetadata( final String link ) {
         if( m_wysiwygEditorMode ) {
-            m_currentElement.addContent( "[" + link + "]" );
+            m_currentElement.addContent( "[" + TextUtil.escapeHTMLEntities( link ) + "]" );
         }
 
         try {
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
index ae121de88..63f718cf1 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/PluginContent.java
@@ -32,6 +32,7 @@ import org.apache.wiki.api.plugin.Plugin;
 import org.apache.wiki.api.plugin.PluginElement;
 import org.apache.wiki.plugin.PluginManager;
 import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.util.TextUtil;
 import org.apache.wiki.variables.VariableManager;
 import org.jdom2.Text;
 
@@ -147,8 +148,10 @@ public class PluginContent extends Text implements PluginElement {
             if( wysiwygEditorMode && !m_pluginName.matches( EMITTABLE_PLUGINS ) ) {
                 result = PLUGIN_START + m_pluginName + SPACE;
 
-                // convert newlines to <br> in case the plugin has a body.
-                final String cmdLine = m_params.get( CMDLINE ).replaceAll( LINEBREAK, ELEMENT_BR );
+                // escape the raw command line first: this text node is emitted with output escaping
+                // disabled, so unescaped markup would reach the wysiwyg editor (and its <textarea>)
+                // as live HTML.  Then convert newlines to <br> in case the plugin has a body.
+                final String cmdLine = TextUtil.escapeHTMLEntities( m_params.get( CMDLINE ) ).replaceAll( LINEBREAK, ELEMENT_BR );
                 result = result + cmdLine + PLUGIN_END;
             } else {
                 final Boolean b = context.getVariable( Context.VAR_EXECUTE_PLUGINS );
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java b/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
index dadf54f6f..67736f3e7 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/render/WysiwygEditingRendererTest.java
@@ -49,8 +49,15 @@ public class WysiwygEditingRendererTest {
     }
 
     private String render( final String s ) throws IOException {
+        return render( s, false );
+    }
+
+    private String render( final String s, final boolean wysiwygEditorMode ) throws IOException {
         final Page dummyPage = Wiki.contents().page(testEngine,"TestPage");
         final Context ctx = Wiki.context().create(testEngine,dummyPage);
+        if( wysiwygEditorMode ) {
+            ctx.setVariable( Context.VAR_WYSIWYG_EDITOR_MODE, Boolean.TRUE );
+        }
 
         final StringReader in = new StringReader(s);
 
@@ -92,4 +99,23 @@ public class WysiwygEditingRendererTest {
         Assertions.assertEquals( "<a class=\"createpage\" href=\"Non-existent Pagename with Spaces\">Non-existent Pagename with Spaces</a>", render(src) );
     }
 
+    /**
+     * The wysiwyg render path echoes raw plugin command lines, access rules and metadata back into the
+     * generated HTML with output escaping disabled.  Unescaped markup there breaks out of the wysiwyg
+     * editors' &lt;textarea&gt; (stored XSS).  See the textarea sinks in templates/editors/*.jsp.
+     */
+    @Test
+    public void testWysiwygEchoedMarkupIsEscaped() throws Exception {
+        final String payload = "</textarea><script>alert(1)</script>";
+
+        String html = render( "[{SomePlugin " + payload + "}]", true );
+        Assertions.assertFalse( html.contains( payload ), html );
+
+        html = render( "[{SET foo='" + payload + "'}]", true );
+        Assertions.assertFalse( html.contains( payload ), html );
+
+        html = render( "[{ALLOW edit " + payload + "}]", true );
+        Assertions.assertFalse( html.contains( payload ), html );
+    }
+
 }
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
index ea787af37..142aee0be 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/CKeditor.jsp
@@ -167,7 +167,7 @@
       </fieldset>
     </wiki:CheckRequestContext>
 
-    <textarea name="htmlPageText"><%=pageAsHtml%></textarea>
+    <textarea name="htmlPageText"><%=pageAsHtml.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")%></textarea>
 </form>
 <script type="text/javascript">
 //<![CDATA[
diff --git a/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp b/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
index 36f6ca647..c317bf33d 100644
--- a/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
+++ b/jspwiki-war/src/main/webapp/templates/210/editors/TinyMCE.jsp
@@ -163,7 +163,7 @@
       </fieldset>
     </wiki:CheckRequestContext>
 
-    <textarea name="htmlPageText"><%=pageAsHtml%></textarea>
+    <textarea name="htmlPageText"><%=pageAsHtml.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")%></textarea>
 </form>
 <script type="text/javascript">
 //<![CDATA[
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
index 4899c1387..65447c499 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/CKeditor.jsp
@@ -255,7 +255,7 @@
   <div class="row edit-area livepreview previewcolumn"><%-- .livepreview  .previewcolumn--%>
       <div>
         <textarea name="htmlPageText"
-             autofocus="autofocus"><%=pageAsHtml.replace("&", "&amp;")%></textarea>
+             autofocus="autofocus"><%=pageAsHtml.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")%></textarea>
       </div>
       <div class="ajaxpreview" >Preview comes here</div>
   </div>
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
index 29a161c67..81e3e5c0d 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/TinyMCE.jsp
@@ -259,7 +259,7 @@
   <div class="row edit-area livepreview previewcolumn"><%-- .livepreview  .previewcolumn--%>
       <div>
         <textarea name="htmlPageText"
-             autofocus="autofocus"><%=pageAsHtml.replace("&", "&amp;")%></textarea>
+             autofocus="autofocus"><%=pageAsHtml.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")%></textarea>
       </div>
       <div class="ajaxpreview" >Preview comes here</div>
   </div>
diff --git a/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp b/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
index b4b011622..2b92803ce 100644
--- a/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
+++ b/jspwiki-war/src/main/webapp/templates/default/editors/wysiwyg.jsp
@@ -257,7 +257,7 @@
         To avoid this, double escape the & char =>  so &amp;lt; is converted to &lt;
         --%>
         <textarea name="htmlPageText"
-             autofocus="autofocus"><%= pageAsHtml.replace("&", "&amp;")%></textarea>
+             autofocus="autofocus"><%= pageAsHtml.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")%></textarea>
       </div>
       <div class="ajaxpreview">Preview comes here</div>
   </div>