--- Begin Message ---
Package: libstruts1.2-java
Severity: important
Tags: patch, security
Hi,
the following CVE (Common Vulnerabilities & Exposures) id was
published for libstruts1.2-java.
CVE-2008-2025[0]:
| Cross-site scripting (XSS) vulnerability in Apache Struts before
| 1.2.9-162.31.1 on SUSE Linux Enterprise (SLE) 11, before 1.2.9-108.2
| on SUSE openSUSE 10.3, before 1.2.9-198.2 on SUSE openSUSE 11.0, and
| before 1.2.9-162.163.2 on SUSE openSUSE 11.1 allows remote attackers
| to inject arbitrary web script or HTML via unspecified vectors related
| to "insufficient quoting of parameters."
The attached patch should be the one that was used by Suse. Please check
and consider uploading. Also, please check the stable/oldstable version.
If you fix the vulnerability please also make sure to include the
CVE id in your changelog entry.
Cheers
Steffen
For further information see:
[0] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-2025
http://security-tracker.debian.net/tracker/CVE-2008-2025
diff --git a/src/org/apache/struts/taglib/html/BaseHandlerTag.java b/src/org/apache/struts/taglib/html/BaseHandlerTag.java
index 403ff97..095045c 100644
--- a/src/org/apache/struts/taglib/html/BaseHandlerTag.java
+++ b/src/org/apache/struts/taglib/html/BaseHandlerTag.java
@@ -35,6 +35,7 @@ import org.apache.struts.taglib.TagUtils;
import org.apache.struts.taglib.logic.IterateTag;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
+import org.apache.struts.util.ResponseUtils;
/**
* Base class for tags that render form elements capable of including JavaScript
@@ -898,10 +899,12 @@ public abstract class BaseHandlerTag extends BodyTagSupport {
*/
protected void prepareAttribute(StringBuffer handlers, String name, Object value) {
if (value != null) {
+ if (name.indexOf('"') >= 0)
+ throw new IllegalArgumentException("quote character in attribute name");
handlers.append(" ");
handlers.append(name);
handlers.append("=\"");
- handlers.append(value);
+ handlers.append(ResponseUtils.filterIfQuote(value.toString()));
handlers.append("\"");
}
}
diff --git a/src/org/apache/struts/taglib/html/BaseTag.java b/src/org/apache/struts/taglib/html/BaseTag.java
index 8c5214b..004ff6a 100644
--- a/src/org/apache/struts/taglib/html/BaseTag.java
+++ b/src/org/apache/struts/taglib/html/BaseTag.java
@@ -30,6 +30,7 @@ import org.apache.struts.Globals;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
+import org.apache.struts.util.ResponseUtils;
/**
* Renders an HTML <base> element with an href
@@ -112,13 +113,14 @@ public class BaseTag extends TagSupport {
String uri) {
StringBuffer tag = new StringBuffer("<base href=\"");
- tag.append(RequestUtils.createServerUriStringBuffer(scheme,serverName,port,uri).toString());
+ tag.append(ResponseUtils.filterIfQuote(
+ RequestUtils.createServerUriStringBuffer(scheme,serverName,port,uri).toString()));
tag.append("\"");
if (this.target != null) {
tag.append(" target=\"");
- tag.append(this.target);
+ tag.append(ResponseUtils.filterIfQuote(this.target));
tag.append("\"");
}
diff --git a/src/org/apache/struts/taglib/html/FormTag.java b/src/org/apache/struts/taglib/html/FormTag.java
index e8eb9b4..070d090 100644
--- a/src/org/apache/struts/taglib/html/FormTag.java
+++ b/src/org/apache/struts/taglib/html/FormTag.java
@@ -37,6 +37,7 @@ import org.apache.struts.config.ModuleConfig;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
+import org.apache.struts.util.ResponseUtils;
/**
* Custom tag that represents an input form, associated with a bean whose
@@ -547,10 +548,10 @@ public class FormTag extends TagSupport {
results.append(" action=\"");
results.append(
- response.encodeURL(
+ ResponseUtils.filterIfQuote(response.encodeURL(
TagUtils.getInstance().getActionMappingURL(
this.action,
- this.pageContext)));
+ this.pageContext))));
results.append("\"");
}
@@ -580,7 +581,7 @@ public class FormTag extends TagSupport {
results.append("<div><input type=\"hidden\" name=\"");
results.append(Constants.TOKEN_KEY);
results.append("\" value=\"");
- results.append(token);
+ results.append(ResponseUtils.filterIfQuote(token));
if (this.isXhtml()) {
results.append("\" />");
} else {
@@ -599,9 +600,10 @@ public class FormTag extends TagSupport {
protected void renderAttribute(StringBuffer results, String attribute, String value) {
if (value != null) {
results.append(" ");
- results.append(attribute);
+ if (attribute.indexOf('"') >= 0)
+ throw new IllegalArgumentException("quote character in attribute name");
results.append("=\"");
- results.append(value);
+ results.append(ResponseUtils.filterIfQuote(value));
results.append("\"");
}
}
diff --git a/src/org/apache/struts/taglib/html/HtmlTag.java b/src/org/apache/struts/taglib/html/HtmlTag.java
index fb64875..d4da38d 100644
--- a/src/org/apache/struts/taglib/html/HtmlTag.java
+++ b/src/org/apache/struts/taglib/html/HtmlTag.java
@@ -29,6 +29,7 @@ import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.Globals;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
+import org.apache.struts.util.ResponseUtils;
/**
* Renders an HTML <html> element with appropriate language attributes if
@@ -151,20 +152,20 @@ public class HtmlTag extends TagSupport {
if ((this.lang || this.locale || this.xhtml) && validLanguage) {
sb.append(" lang=\"");
- sb.append(language);
+ sb.append(ResponseUtils.filterIfQuote(language));
if (validCountry) {
sb.append("-");
- sb.append(country);
+ sb.append(ResponseUtils.filterIfQuote(country));
}
sb.append("\"");
}
if (this.xhtml && validLanguage) {
sb.append(" xml:lang=\"");
- sb.append(language);
+ sb.append(ResponseUtils.filterIfQuote(language));
if (validCountry) {
sb.append("-");
- sb.append(country);
+ sb.append(ResponseUtils.filterIfQuote(country));
}
sb.append("\"");
}
diff --git a/src/org/apache/struts/taglib/html/JavascriptValidatorTag.java b/src/org/apache/struts/taglib/html/JavascriptValidatorTag.java
index 77d7dba..11269f7 100644
--- a/src/org/apache/struts/taglib/html/JavascriptValidatorTag.java
+++ b/src/org/apache/struts/taglib/html/JavascriptValidatorTag.java
@@ -46,6 +46,7 @@ import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
+import org.apache.struts.util.ResponseUtils;
import org.apache.struts.validator.Resources;
import org.apache.struts.validator.ValidatorPlugIn;
@@ -850,7 +851,7 @@ public class JavascriptValidatorTag extends BodyTagSupport {
}
if (this.src != null) {
- start.append(" src=\"" + src + "\"");
+ start.append(" src=\"" + ResponseUtils.filterIfQuote(src) + "\"");
}
start.append("> \n");
diff --git a/src/org/apache/struts/taglib/html/OptionTag.java b/src/org/apache/struts/taglib/html/OptionTag.java
index 4df5c95..9f786bc 100644
--- a/src/org/apache/struts/taglib/html/OptionTag.java
+++ b/src/org/apache/struts/taglib/html/OptionTag.java
@@ -26,6 +26,8 @@ import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.struts.Globals;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
+import org.apache.struts.util.ResponseUtils;
+import org.apache.struts.util.ResponseUtilsTest;
/**
* Tag for select options. The body of this tag is presented to the user
@@ -235,7 +237,7 @@ public class OptionTag extends BodyTagSupport {
protected String renderOptionElement() throws JspException {
StringBuffer results = new StringBuffer("<option value=\"");
- results.append(this.value);
+ results.append(ResponseUtils.filterIfQuote(this.value));
results.append("\"");
if (disabled) {
results.append(" disabled=\"disabled\"");
@@ -245,17 +247,17 @@ public class OptionTag extends BodyTagSupport {
}
if (style != null) {
results.append(" style=\"");
- results.append(style);
+ results.append(ResponseUtils.filterIfQuote(style));
results.append("\"");
}
if (styleId != null) {
results.append(" id=\"");
- results.append(styleId);
+ results.append(ResponseUtils.filterIfQuote(styleId));
results.append("\"");
}
if (styleClass != null) {
results.append(" class=\"");
- results.append(styleClass);
+ results.append(ResponseUtils.filterIfQuote(styleClass));
results.append("\"");
}
results.append(">");
diff --git a/src/org/apache/struts/taglib/html/OptionsCollectionTag.java b/src/org/apache/struts/taglib/html/OptionsCollectionTag.java
index 9999259..b972788 100644
--- a/src/org/apache/struts/taglib/html/OptionsCollectionTag.java
+++ b/src/org/apache/struts/taglib/html/OptionsCollectionTag.java
@@ -30,6 +30,7 @@ import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.util.IteratorAdapter;
+import org.apache.struts.util.ResponseUtils;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
@@ -291,7 +292,7 @@ public class OptionsCollectionTag extends TagSupport {
if (filter) {
sb.append(TagUtils.getInstance().filter(value));
} else {
- sb.append(value);
+ sb.append(ResponseUtils.filterIfQuote(value));
}
sb.append("\"");
if (matched) {
@@ -299,12 +300,12 @@ public class OptionsCollectionTag extends TagSupport {
}
if (style != null) {
sb.append(" style=\"");
- sb.append(style);
+ sb.append(ResponseUtils.filterIfQuote(style));
sb.append("\"");
}
if (styleClass != null) {
sb.append(" class=\"");
- sb.append(styleClass);
+ sb.append(ResponseUtils.filterIfQuote(styleClass));
sb.append("\"");
}
diff --git a/src/org/apache/struts/taglib/html/OptionsTag.java b/src/org/apache/struts/taglib/html/OptionsTag.java
index 90d716a..2f11c3e 100644
--- a/src/org/apache/struts/taglib/html/OptionsTag.java
+++ b/src/org/apache/struts/taglib/html/OptionsTag.java
@@ -30,6 +30,7 @@ import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.util.IteratorAdapter;
+import org.apache.struts.util.ResponseUtils;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
@@ -313,7 +314,7 @@ public class OptionsTag extends TagSupport {
if (filter) {
sb.append(TagUtils.getInstance().filter(value));
} else {
- sb.append(value);
+ sb.append(ResponseUtils.filterIfQuote(value));
}
sb.append("\"");
if (matched) {
@@ -321,12 +322,12 @@ public class OptionsTag extends TagSupport {
}
if (style != null) {
sb.append(" style=\"");
- sb.append(style);
+ sb.append(ResponseUtils.filterIfQuote(style));
sb.append("\"");
}
if (styleClass != null) {
sb.append(" class=\"");
- sb.append(styleClass);
+ sb.append(ResponseUtils.filterIfQuote(styleClass));
sb.append("\"");
}
diff --git a/src/org/apache/struts/taglib/html/RewriteTag.java b/src/org/apache/struts/taglib/html/RewriteTag.java
index 804e50c..41e82ae 100644
--- a/src/org/apache/struts/taglib/html/RewriteTag.java
+++ b/src/org/apache/struts/taglib/html/RewriteTag.java
@@ -24,6 +24,7 @@ import java.util.Map;
import javax.servlet.jsp.JspException;
import org.apache.struts.taglib.TagUtils;
+import org.apache.struts.util.ResponseUtils;
/**
* Generate a URL-encoded URI as a string.
@@ -72,7 +73,8 @@ public class RewriteTag extends LinkTag {
(messages.getMessage("rewrite.url", e.toString()));
}
- TagUtils.getInstance().write(pageContext, url);
+ TagUtils.getInstance().write(pageContext,
+ ResponseUtils.filterIfQuote(url));
return (SKIP_BODY);
diff --git a/src/org/apache/struts/util/ResponseUtils.java b/src/org/apache/struts/util/ResponseUtils.java
index 4588bb2..ce377b9 100644
--- a/src/org/apache/struts/util/ResponseUtils.java
+++ b/src/org/apache/struts/util/ResponseUtils.java
@@ -136,8 +136,37 @@ public class ResponseUtils {
return result == null ? value : result.toString();
}
-
-
+ /**
+ * Replace double-quote characters in the input string with
+ * proper HTML encoding.
+ *
+ * No other HTML-encoding is performed. As a result, the return value
+ * can only be safely used in (X)HTML attributes surrounded by
+ * double-quote characters (<code>"</code>).
+ *
+ * <p>Note that you should not use this function in new code.
+ * It is only intended for old code which needs to be
+ * backwards-compatible with incompletely-quoted attributes.
+ *
+ * @return a fresh string object if quoting is needed,
+ * otherwise the input string
+ */
+ public static String filterIfQuote(String value) {
+ if (value == null)
+ return null;
+ if (value.indexOf('"') >= 0) {
+ StringBuffer sb = new StringBuffer(value.length() + 2);
+ for (int i = 0; i < value.length(); ++i) {
+ final char ch = value.charAt(i);
+ if (ch == '"')
+ sb.append(""");
+ else
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+ return value;
+ }
/**
* <p>URLencodes a string assuming the character encoding is UTF-8.</p>
[4. text/x-diff; CVE-2008-2141-a.diff]...
--- a/src/org/apache/portals/bridges/struts/taglib/ELRewriteTag.java
+++ b/src/org/apache/portals/bridges/struts/taglib/ELRewriteTag.java
@@ -141,7 +141,7 @@ public class ELRewriteTag extends org.apache.strutsel.taglib.html.ELRewriteTag
{
pageContext.popBody();
}
- TagUtils.getInstance().write(pageContext, url);
+ TagUtils.getInstance().write(pageContext, ResponseUtils.filterIfQuote(url));
return (SKIP_BODY);
}
else
diff --git a/src/org/apache/portals/bridges/struts/taglib/RewriteTag.java b/src/org/apache/portals/bridges/struts/taglib/RewriteTag.java
index cdfa825..4a2a58c 100644
--- a/src/org/apache/portals/bridges/struts/taglib/RewriteTag.java
+++ b/src/org/apache/portals/bridges/struts/taglib/RewriteTag.java
@@ -22,6 +22,7 @@ import javax.servlet.jsp.tagext.BodyContent;
import org.apache.portals.bridges.struts.PortletServlet;
import org.apache.portals.bridges.struts.config.PortletURLTypes; // javadoc
import org.apache.struts.taglib.TagUtils;
+import org.apache.struts.util.ResponseUtils;
/**
* Supports the Struts html:rewrite tag to be used within a Portlet context.
@@ -122,7 +123,7 @@ public class RewriteTag extends org.apache.struts.taglib.html.RewriteTag
{
pageContext.popBody();
}
- TagUtils.getInstance().write(pageContext, url);
+ TagUtils.getInstance().write(pageContext, ResponseUtils.filterIfQuote(url));
return (SKIP_BODY);
}
else
diff --git a/src/org/apache/portals/bridges/struts/taglib/ScriptTag.java b/src/org/apache/portals/bridges/struts/taglib/ScriptTag.java
index abc1875..d79b586 100644
--- a/src/org/apache/portals/bridges/struts/taglib/ScriptTag.java
+++ b/src/org/apache/portals/bridges/struts/taglib/ScriptTag.java
@@ -22,6 +22,8 @@ import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
+import org.apache.struts.util.ResponseUtils;
+
/**
* Generate a script tag for use within a Portlet environment.
* <p>
@@ -74,7 +76,7 @@ public class ScriptTag extends TagSupport
{
StringBuffer buffer = new StringBuffer("<script language=\"");
if (language != null)
- buffer.append(language);
+ buffer.append(ResponseUtils.filterIfQuote(language));
else
buffer.append("Javascript1.1");
buffer.append("\" src=\"");
@@ -82,11 +84,12 @@ public class ScriptTag extends TagSupport
{
buffer.append(((HttpServletRequest) pageContext.getRequest())
.getContextPath());
- buffer.append(src);
+ buffer.append(ResponseUtils.filterIfQuote(src));
}
else
{
- buffer.append(TagsSupport.getContextRelativeURL(pageContext,src,true));
+ buffer.append(ResponseUtils.filterIfQuote(
+ TagsSupport.getContextRelativeURL(pageContext,src,true)));
}
buffer.append("\"/></script>");
JspWriter writer = pageContext.getOut();
diff --git a/src/org/apache/portals/bridges/struts/taglib/TagsSupport.java b/src/org/apache/portals/bridges/struts/taglib/TagsSupport.java
index f5a2d74..a75161f 100644
--- a/src/org/apache/portals/bridges/struts/taglib/TagsSupport.java
+++ b/src/org/apache/portals/bridges/struts/taglib/TagsSupport.java
@@ -23,6 +23,7 @@ import org.apache.portals.bridges.struts.StrutsPortlet;
import org.apache.portals.bridges.struts.StrutsPortletURL;
import org.apache.portals.bridges.struts.config.StrutsPortletConfig;
import org.apache.portals.bridges.struts.config.PortletURLTypes; // javadoc
+import org.apache.struts.util.ResponseUtils;
/**
* Utility class providing common Struts Bridge Tags functionality.
@@ -152,8 +153,9 @@ class TagsSupport
String actionURL = formStartElement.substring(actionURLStart,
actionURLEnd);
formStartElement = formStartElement.substring(0, actionURLStart)
- + StrutsPortletURL.createActionURL(pageContext.getRequest(),
- actionURL).toString()
+ + ResponseUtils.filterIfQuote(
+ StrutsPortletURL.createActionURL(pageContext.getRequest(),
+ actionURL).toString())
+ formStartElement.substring(actionURLEnd);
}
return formStartElement;
--- End Message ---