diff --git a/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java b/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java index e9237b9e09..8115207e1f 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/parser/MarkupParser.java @@ -326,12 +326,17 @@ protected void pushBack( final int c ) throws IOException { /** * Writes HTML for error message. Does not add it to the document, you have to do it yourself. + *

+ * The error string is HTML-escaped here, because the wiki rendering pipeline serializes the + * document with output escaping disabled, so any markup in the message would otherwise be + * emitted verbatim into the page (e.g. attacker-controlled plugin parameters echoed back in + * exception messages). * * @param error The error string. * @return An Element containing the error. */ public static Element makeError( final String error ) { - return new Element( "span" ).setAttribute( "class", "error" ).addContent( error ); + return new Element( "span" ).setAttribute( "class", "error" ).addContent( TextUtil.replaceEntities( error ) ); } /** diff --git a/jspwiki-main/src/test/java/org/apache/wiki/parser/MarkupParserTest.java b/jspwiki-main/src/test/java/org/apache/wiki/parser/MarkupParserTest.java index a60123fa24..9d846570be 100644 --- a/jspwiki-main/src/test/java/org/apache/wiki/parser/MarkupParserTest.java +++ b/jspwiki-main/src/test/java/org/apache/wiki/parser/MarkupParserTest.java @@ -43,4 +43,13 @@ public void testCleanLink3() Assertions.assertEquals( "Clean (link)", MarkupParser.cleanLink("Clean (link)") ); } + @Test + public void testMakeErrorEscapesHtml() + { + // Error messages are rendered with output escaping disabled, so makeError must + // neutralize markup carried in e.g. plugin exception messages. + final String text = MarkupParser.makeError( "Faulty pattern " ).getText(); + Assertions.assertEquals( "Faulty pattern <img src=x onerror=alert(1)>", text ); + } + }