From: Henri Sara Date: Tue, 27 Sep 2011 08:35:12 +0000 (+0000) Subject: #7671 Do not permit HTML in system messages and normal error messages, XHTML mode... X-Git-Tag: 6.7.0.rc1~11^2~3 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=36e62e95b9fba99f4a7c2da7c4a1923458c21c45;p=vaadin-framework.git #7671 Do not permit HTML in system messages and normal error messages, XHTML mode for UserError svn changeset:21327/svn branch:6.6 --- diff --git a/src/com/vaadin/data/Validator.java b/src/com/vaadin/data/Validator.java index 21a9da9f97..b1dc5ffc14 100644 --- a/src/com/vaadin/data/Validator.java +++ b/src/com/vaadin/data/Validator.java @@ -9,6 +9,7 @@ import java.io.Serializable; import com.vaadin.terminal.ErrorMessage; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; /** * Interface that implements a method for validating if an {@link Object} is @@ -63,6 +64,12 @@ public interface Validator extends Serializable { /** * Exception that is thrown by a {@link Validator} when a value is invalid. * + *

+ * The default implementation of InvalidValueException does not support HTML + * in error messages. To enable HTML support, override + * {@link #getHtmlMessage()} and use the subclass in validators. + *

+ * * @author IT Mill Ltd. * @version * @VERSION@ @@ -154,7 +161,7 @@ public interface Validator extends Serializable { target.addAttribute("level", "error"); // Error message - final String message = getLocalizedMessage(); + final String message = getHtmlMessage(); if (message != null) { target.addText(message); } @@ -167,6 +174,16 @@ public interface Validator extends Serializable { target.endTag("error"); } + /** + * Returns the message of the error in HTML. + * + * Note that this API may change in future versions. + */ + protected String getHtmlMessage() { + return AbstractApplicationServlet + .safeEscapeForHtml(getLocalizedMessage()); + } + /* * (non-Javadoc) * diff --git a/src/com/vaadin/data/validator/AbstractValidator.java b/src/com/vaadin/data/validator/AbstractValidator.java index 7d4f1c3a0d..ee2fee893c 100644 --- a/src/com/vaadin/data/validator/AbstractValidator.java +++ b/src/com/vaadin/data/validator/AbstractValidator.java @@ -15,6 +15,12 @@ import com.vaadin.data.Validator; * (converted to string using {@link #toString()}) or "null" if the value is * null. *

+ *

+ * The default implementation of AbstractValidator does not support HTML in + * error messages. To enable HTML support, override + * {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from + * {@link #validate(Object)}. + *

* * @author IT Mill Ltd. * @version diff --git a/src/com/vaadin/terminal/SystemError.java b/src/com/vaadin/terminal/SystemError.java index 8b721c07f5..fb1de0c494 100644 --- a/src/com/vaadin/terminal/SystemError.java +++ b/src/com/vaadin/terminal/SystemError.java @@ -7,12 +7,18 @@ package com.vaadin.terminal; import java.io.PrintWriter; import java.io.StringWriter; +import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; + /** * SystemError is a runtime exception caused by error in system. * The system error can be shown to the user as it implements * ErrorMessage interface, but contains technical information such * as stack trace and exception. * + * SystemError does not support HTML in error messages or stack traces. If HTML + * messages are required, use {@link UserError} or a custom implementation of + * {@link ErrorMessage}. + * * @author IT Mill Ltd. * @version * @VERSION@ @@ -75,11 +81,26 @@ public class SystemError extends RuntimeException implements ErrorMessage { target.startTag("error"); target.addAttribute("level", "system"); + String message = getHtmlMessage(); + + target.addXMLSection("div", message, + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); + + target.endTag("error"); + + } + + /** + * Returns the message of the error in HTML. + * + * Note that this API may change in future versions. + */ + protected String getHtmlMessage() { StringBuilder sb = new StringBuilder(); final String message = getLocalizedMessage(); if (message != null) { sb.append("

"); - sb.append(message); + sb.append(AbstractApplicationServlet.safeEscapeForHtml(message)); sb.append("

"); } @@ -89,15 +110,11 @@ public class SystemError extends RuntimeException implements ErrorMessage { final StringWriter buffer = new StringWriter(); cause.printStackTrace(new PrintWriter(buffer)); sb.append("
");
-            sb.append(buffer.toString());
+            sb.append(AbstractApplicationServlet.safeEscapeForHtml(buffer
+                    .toString()));
             sb.append("
"); } - - target.addXMLSection("div", sb.toString(), - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); - - target.endTag("error"); - + return sb.toString(); } /** diff --git a/src/com/vaadin/terminal/UserError.java b/src/com/vaadin/terminal/UserError.java index bcce0ed283..d33c02d144 100644 --- a/src/com/vaadin/terminal/UserError.java +++ b/src/com/vaadin/terminal/UserError.java @@ -4,6 +4,8 @@ package com.vaadin.terminal; +import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; + /** * UserError is a controlled error occurred in application. User * errors are occur in normal usage of the application and guide the user. @@ -32,6 +34,11 @@ public class UserError implements ErrorMessage { */ public static final int CONTENT_UIDL = 2; + /** + * Content mode, where the error contains XHTML. + */ + public static final int CONTENT_XHTML = 3; + /** * Content mode. */ @@ -80,24 +87,24 @@ public class UserError implements ErrorMessage { level = errorLevel; } - /* Documenten in interface */ + /* Documented in interface */ public int getErrorLevel() { return level; } - /* Documenten in interface */ + /* Documented in interface */ public void addListener(RepaintRequestListener listener) { } - /* Documenten in interface */ + /* Documented in interface */ public void removeListener(RepaintRequestListener listener) { } - /* Documenten in interface */ + /* Documented in interface */ public void requestRepaint() { } - /* Documenten in interface */ + /* Documented in interface */ public void paint(PaintTarget target) throws PaintException { target.startTag("error"); @@ -118,21 +125,25 @@ public class UserError implements ErrorMessage { // Paint the message switch (mode) { case CONTENT_TEXT: - target.addText(msg); + target.addText(AbstractApplicationServlet.safeEscapeForHtml(msg)); break; case CONTENT_UIDL: target.addUIDL(msg); break; case CONTENT_PREFORMATTED: - target.startTag("pre"); + target.addText("
"
+                    + AbstractApplicationServlet.safeEscapeForHtml(msg)
+                    + "
"); + break; + case CONTENT_XHTML: target.addText(msg); - target.endTag("pre"); + break; } target.endTag("error"); } - /* Documenten in interface */ + /* Documented in interface */ public void requestRepaintRequests() { } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index 784ecb262b..da55aa7fa0 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -449,9 +449,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource /** *

- * Gets the component's description. The description can be used to briefly - * describe the state of the component to the user. The description string - * may contain certain XML tags: + * Gets the component's description, used in tooltips and can be displayed + * directly in certain other components such as forms. The description can + * be used to briefly describe the state of the component to the user. The + * description string may contain certain XML tags: *

* *

@@ -513,6 +514,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource * {@link com.vaadin.terminal.Paintable.RepaintRequestEvent * RepaintRequestEvent}. * + * The description is displayed as HTML/XHTML in tooltips or directly in + * certain components so care should be taken to avoid creating the + * possibility for HTML injection and possibly XSS vulnerabilities. + * * @param description * the new description string for the component. */ diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index 73140fd79a..877171232e 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -105,7 +105,7 @@ public class Panel extends AbstractComponentContainer implements Scrollable, * Creates a new empty panel with caption. Default layout is used. * * @param caption - * the caption used in the panel. + * the caption used in the panel (HTML/XHTML). */ public Panel(String caption) { this(caption, null); @@ -115,7 +115,7 @@ public class Panel extends AbstractComponentContainer implements Scrollable, * Creates a new empty panel with the given caption and content. * * @param caption - * the caption of the panel. + * the caption of the panel (HTML/XHTML). * @param content * the content used in the panel. */ @@ -124,6 +124,20 @@ public class Panel extends AbstractComponentContainer implements Scrollable, setCaption(caption); } + /** + * Sets the caption of the panel. + * + * Note that the caption is interpreted as HTML/XHTML and therefore care + * should be taken not to enable HTML injection and XSS attacks using panel + * captions. This behavior may change in future versions. + * + * @see AbstractComponent#setCaption(String) + */ + @Override + public void setCaption(String caption) { + super.setCaption(caption); + } + /** * Gets the current layout of the panel. *