WW-3224 fix possible cross site scripting

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@805635 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Musachy Barroso
2009-08-19 00:18:54 +00:00
parent c9d10a6b05
commit 0bf060b69c
15 changed files with 189 additions and 7 deletions
@@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.commons.lang.xwork.StringUtils;
import com.opensymphony.xwork2.util.ValueStack;
@@ -36,7 +37,8 @@ import java.util.List;
* <!-- START SNIPPET: javadoc -->
*
* Render action errors if they exists the specific layout of the rendering depends on
* the theme itself. Empty (null or blank string) errors will not be printed.
* the theme itself. Empty (null or blank string) errors will not be printed. The action error
* strings will be html escaped by default.
*
* <!-- END SNIPPET: javadoc -->
*
@@ -58,7 +60,7 @@ import java.util.List;
public class ActionError extends UIBean {
public static final String TEMPLATE = "actionerror";
private boolean escape = true;
public ActionError(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
@@ -81,5 +83,11 @@ public class ActionError extends UIBean {
}
addParameter("isEmptyList", isEmptyList);
addParameter("escape", escape);
}
@StrutsTagAttribute(description=" Whether to escape HTML", type="Boolean", defaultValue="true")
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.commons.lang.xwork.StringUtils;
import com.opensymphony.xwork2.util.ValueStack;
@@ -36,7 +37,8 @@ import java.util.Collection;
* <!-- START SNIPPET: javadoc -->
*
* Render action messages if they exists, specific rendering layout depends on the
* theme itself. Empty (null or blank string) messages will not be printed.
* theme itself. Empty (null or blank string) messages will not be printed. The action message
* strings will be html escaped by default.
*
* <!-- END SNIPPET: javadoc -->
*
@@ -56,6 +58,7 @@ import java.util.Collection;
public class ActionMessage extends UIBean {
private static final String TEMPLATE = "actionmessage";
protected boolean escape = true;
public ActionMessage(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
@@ -78,5 +81,11 @@ public class ActionMessage extends UIBean {
}
addParameter("isEmptyList", isEmptyList);
addParameter("escape", escape);
}
@StrutsTagAttribute(description=" Whether to escape HTML", type="Boolean", defaultValue="true")
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -35,6 +35,7 @@ import java.util.List;
* <!-- START SNIPPET: javadoc -->
*
* Render field errors if they exists. Specific layout depends on the particular theme.
* The field error strings will be html escaped by default.
*
* <!-- END SNIPPET: javadoc -->
*
@@ -91,6 +92,7 @@ import java.util.List;
public class FieldError extends UIBean implements UnnamedParametric {
private List<String> errorFieldNames = new ArrayList<String>();
private boolean escape = true;
public FieldError(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
@@ -107,7 +109,9 @@ public class FieldError extends UIBean implements UnnamedParametric {
super.evaluateExtraParams();
if (errorFieldNames != null)
addParameter("errorFieldNames", errorFieldNames);
addParameter("errorFieldNames", errorFieldNames);
addParameter("escape", escape);
}
public void addParameter(Object value) {
@@ -124,5 +128,10 @@ public class FieldError extends UIBean implements UnnamedParametric {
public void setFieldName(String fieldName) {
addParameter(fieldName);
}
@StrutsTagAttribute(description=" Whether to escape HTML", type="Boolean", defaultValue="true")
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -37,8 +37,20 @@ public class ActionErrorTag extends AbstractUITag {
private static final long serialVersionUID = -3710234378022378639L;
private boolean escape = true;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new ActionError(stack, req, res);
}
protected void populateParams() {
super.populateParams();
ActionError error = (ActionError) component;
error.setEscape(escape);
}
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.ActionMessage;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.ActionError;
import com.opensymphony.xwork2.util.ValueStack;
@@ -37,7 +38,20 @@ public class ActionMessageTag extends AbstractUITag {
private static final long serialVersionUID = 243396927554182506L;
private boolean escape = true;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new ActionMessage(stack, req, res);
}
protected void populateParams() {
super.populateParams();
ActionMessage message = (ActionMessage) component;
message.setEscape(escape);
}
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -37,6 +37,7 @@ public class FieldErrorTag extends AbstractUITag {
private static final long serialVersionUID = -182532967507726323L;
protected String fieldName;
protected boolean escape = true;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
@@ -48,10 +49,15 @@ public class FieldErrorTag extends AbstractUITag {
FieldError fieldError = ((FieldError) component);
fieldError.setFieldName(this.fieldName);
fieldError.setEscape(escape);
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public void setEscape(boolean escape) {
this.escape = escape;
}
}
@@ -36,7 +36,7 @@
>
<#list actionErrors as error>
<#if error?if_exists != "">
<li><span>${error!}</span></li>
<li><span><#if parameters.escape>${error!?html}<#else>${error!}</#if></span><#rt/></li><#rt/>
</#if>
</#list>
</ul>
@@ -36,7 +36,7 @@
>
<#list actionMessages as message>
<#if message?if_exists != "">
<li><span>${message!}</span></li>
<li><span><#if parameters.escape>${message!?html}<#else>${message!}</#if></span></li>
</#if>
</#list>
</ul>
@@ -73,7 +73,7 @@
<#list eKeys as eKey><#t/>
<#assign eValue = fieldErrors[eKey]><#t/>
<#list eValue as eEachValue><#t/>
<li><span>${eEachValue}</span></li>
<li><span><#if parameters.escape>${eEachValue!?html}<#else>${eEachValue!}</#if></span></li>
</#list><#t/>
</#list><#t/>
</ul>
@@ -81,6 +81,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">Set the html disabled attribute on rendered html element</td>
</tr>
<tr>
<td align="left" valign="top">escape</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">Boolean</td>
<td align="left" valign="top"> Whether to escape HTML</td>
</tr>
<tr>
<td align="left" valign="top">id</td>
<td align="left" valign="top">false</td>
@@ -81,6 +81,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">Set the html disabled attribute on rendered html element</td>
</tr>
<tr>
<td align="left" valign="top">escape</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">Boolean</td>
<td align="left" valign="top"> Whether to escape HTML</td>
</tr>
<tr>
<td align="left" valign="top">id</td>
<td align="left" valign="top">false</td>
@@ -81,6 +81,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">Set the html disabled attribute on rendered html element</td>
</tr>
<tr>
<td align="left" valign="top">escape</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">Boolean</td>
<td align="left" valign="top"> Whether to escape HTML</td>
</tr>
<tr>
<td align="left" valign="top">fieldName</td>
<td align="left" valign="top">false</td>
@@ -24,6 +24,7 @@ package org.apache.struts2.views.jsp.ui;
import java.util.*;
import org.apache.struts2.views.jsp.AbstractUITagTest;
import org.apache.struts2.TestAction;
import org.apache.commons.lang.xwork.StringUtils;
import com.opensymphony.xwork2.Action;
@@ -48,6 +49,38 @@ public class ActionErrorTagTest extends AbstractUITagTest {
verify(ActionErrorTagTest.class.getResource("actionerror-1.txt"));
}
public void testActionErrorsEscape() throws Exception {
ActionErrorTag tag = new ActionErrorTag();
TestAction testAction = new TestAction();
testAction.addActionError("<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(true);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"errorMessage\"><li><span>&lt;p&gt;hey&lt;/p&gt;</span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testActionErrorsDontEscape() throws Exception {
ActionErrorTag tag = new ActionErrorTag();
TestAction testAction = new TestAction();
testAction.addActionError("<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(false);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"errorMessage\"><li><span><p>hey</p></span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testHaveActionErrors() throws Exception {
ActionErrorTag tag = new ActionErrorTag();
@@ -24,6 +24,7 @@ package org.apache.struts2.views.jsp.ui;
import java.util.*;
import org.apache.struts2.views.jsp.AbstractUITagTest;
import org.apache.struts2.TestAction;
import org.apache.commons.lang.xwork.StringUtils;
import com.opensymphony.xwork2.Action;
@@ -46,6 +47,39 @@ public class ActionMessageTagTest extends AbstractUITagTest {
verify(ActionMessageTagTest.class.getResource("actionmessage-1.txt"));
}
public void testActionMessageEscape() throws Exception {
ActionMessageTag tag = new ActionMessageTag();
TestAction testAction = new TestAction();
testAction.addActionMessage("<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(true);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"actionMessage\"><li><span>&lt;p&gt;hey&lt;/p&gt;</span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testActionErrorsDontEscape() throws Exception {
ActionMessageTag tag = new ActionMessageTag();
TestAction testAction = new TestAction();
testAction.addActionMessage("<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(false);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"actionMessage\"><li><span><p>hey</p></span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testYesActionMessages() throws Exception {
ActionMessageTag tag = new ActionMessageTag();
@@ -29,6 +29,7 @@ import java.util.Map;
import org.apache.struts2.views.jsp.AbstractUITagTest;
import org.apache.struts2.views.jsp.ParamTag;
import org.apache.struts2.TestAction;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
@@ -60,6 +61,38 @@ public class FieldErrorTagTest extends AbstractUITagTest {
verify(FieldErrorTagTest.class.getResource("fielderror-2.txt"));
}
public void testFieldErrorsEscape() throws Exception {
FieldErrorTag tag = new FieldErrorTag();
TestAction testAction = new TestAction();
testAction.addFieldError("f", "<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(true);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"errorMessage\"><li><span>&lt;p&gt;hey&lt;/p&gt;</span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testFieldErrorsDontEscape() throws Exception {
FieldErrorTag tag = new FieldErrorTag();
TestAction testAction = new TestAction();
testAction.addFieldError("f", "<p>hey</p>");
stack.pop();
stack.push(testAction);
tag.setEscape(false);
tag.setPageContext(pageContext);
tag.doStartTag();
tag.doEndTag();
assertEquals(normalize("<ul class=\"errorMessage\"><li><span><p>hey</p></span></li></ul>", true),
normalize(writer.toString(), true));
}
public void testWithParamsWithFieldErrors1() throws Exception {
FieldErrorTag tag = new FieldErrorTag();
tag.setId("someid");