Security Research
Showing results for 
Search instead for 
Do you mean 

Protect your Struts1 applications

alvaro_munoz ‎05-01-2014 08:26 AM - edited ‎12-15-2014 02:58 AM

[UPDATE]: Please refer to and install following filter to protect from Classloader maniupulation in Struts1 applications:


Since the last post on how to mitigate the Struts 2 zero day on the wild we have received many queries from customers wondering if their legacy Struts 1 applications were also vulnerable to this same attack.


The Struts security team confirmed that classloader manipulation is also possible in Struts 1 applications even if they don’t use OGNL for parameter binding. They have assigned CVE-2014-0114 to this issue.

Further discussions with Struts security team have confirmed that although classloader manipulation has been verified, remote code execution has not been confirmed yet.

At HP we don’t wait for an exploited zero day before we take action to protect our customers. Therefore, while the Struts team works on a patch for this issue, we strongly recommend Struts1 developers to take the following actions to mitigate the risk.

Struts1 lacks the Struts2 Interceptor chain so we cannot benefit from the Parameter Interceptor to do the work for us. But we can easily build our own using Servlet Filters for the Struts’s org.apache.struts.action.ActionServlet Servlet.

Struts ActionForm bean population relies on ServletRequest.getParameterNames() to first get a list of all parameters being sent on the query and proceed to set those parameter on the ActionForm bean properties.

The following Filter will create a ServletRequest wrapper that overwrites getParameterNames() method and checks the parameter names against a customizable regular expression. If a parameter name matches this regular expression, it will be removed from the list returned by ServletRequest.getParameterNames().

Figure 1:



import java.util.*;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public final class ParamFilter implements Filter {

    FilterConfig filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String regex = this.filterConfig.getInitParameter("excludeParams");
        chain.doFilter(new ParamFilteredRequest(request, regex), response);

    public void destroy() { }
    static class ParamFilteredRequest extends HttpServletRequestWrapper {

        private HttpServletRequest originalRequest;
        private String regex;

        public ParamFilteredRequest(ServletRequest request, String regex) {
            this.originalRequest = (HttpServletRequest) request;
            this.regex = regex;
        public Enumeration getParameterNames() {
            List<String> requestParameterNames = Collections.list((Enumeration<String>) super.getParameterNames());
            List finalParameterNames = new ArrayList();

            for (String parameterName:requestParameterNames) {
                if (!parameterName.matches(regex)) {
                    System.out.println("Param : " + parameterName);
            return Collections.enumeration(finalParameterNames);


Figure 2: Web.xml configuration


        <servlet-name>YOUR ACTION SERVLET</servlet-name>


We would like to thank the Struts security team for their prompt response and their validation of the proposed mitigation filter.


Update (01/05/2014):


HP Security Research Team has confirmed remote code execution is possible on certain application servers and has notified Struts security team.


Stay Secure!

0 Kudos
About the Author


Arturo T
on ‎05-02-2014 12:55 PM

In the original Struts 2 vulnerability documentation, the regular expression also check for the following initial strings followed by a dot:


  • dojo
  • struts
  • session
  • request
  • application
  • servletRequest
  • servletResponse
  • parameters
  • action
  • method

Why the regexp for Struts 1 presented here does not include them? Are they relevant?

on ‎05-03-2014 09:15 AM

Hi Arturo,


Thanks for your comment. Those keywords are relevant if evaluated in the context of the Struts2 Value Stack via OGNL. Struts1 does not use OGNL and has no access to the anything similar to the Value Stack and so they dont suppose a specific risk.




Kishore Kirdat
on ‎05-05-2014 02:01 AM

Is it safe to assume that if I am not using ActionForm, but simple using actions alone, then I am not impacted by this vulnerability?

on ‎05-05-2014 03:15 AM

Hi Kishore,

Thanks for your comment. If there is no ActionForm associated with the action in the action declaration, then Struts will not start the ActionForm binding process and therefore this particular attack vector will not be possible. However we strongly recommend taking all possible mitigation actions to protect your applciations from unknown attack vectors that may be working on the wild.




Patrick Trainor
on ‎05-05-2014 09:01 AM

Thanks for making this code available. What license  applies to it if any?

on ‎05-06-2014 05:05 AM ‎05-06-2014 07:21 AM alvaro_munoz

Here is an improved version of the filter that compiles the pattern only once:

on ‎05-06-2014 07:21 AM

Hi Patrick,


Thanks for your comment. The fix is not licensed in any way and its completely open source so that any one is free to use it or modify it.
It is provided as-is with no guarantees nor support and designed as a temporal workaround until a patch is made available.



on ‎05-07-2014 03:02 PM

Can you tell a sample test URL that we can use to test this logic?

on ‎05-08-2014 01:14 AM

Thanks for the comment pmulay,


Any action associated with an actionForm is vulnerable. URL should look like




Jamie W
on ‎05-09-2014 06:10 PM

how do you test if the vulnerability is there and then verify the fix addressed the issue? The main problem I have is I don't know how to test it the vulnerability and thus can't verify if the issue is really addressed after incorporating this fix. Thanks for any help you can provide.

on ‎05-10-2014 02:55 AM

Hi Jamie,


Thanks for your comment, Im sorry I cannot explain how to verify if the issue has been fixed withouth disclosing the exploit details.


All I can say is that the filter has been tested in our labs and verified by the Struts security team.




William Howard
on ‎05-12-2014 02:16 AM

Thanks for providing the patch!


After analysing the regular expression, did you realise that in your regular expression:




the prefix part can be simplified to:




Is this still what you intended to do?





Reva C
on ‎05-12-2014 02:19 AM

I'm using Struts 1.3.10 with Websphere 8. I tried testing the above fix  in my application by providing urls with parameters like "?class.classLoader.defaultAssertionStatus=true", or "class.classLoader.resource.dircontext.docBase=someText" either case all such parameters are permitted into my application. I see those parameters inside the finalParameters returned by the by getParameters(). Am I testing correctly or am I missing something here? I've placed this ParamFilter as the first filter in the chain in my web.xml file. Thanks in advance.

on ‎05-12-2014 03:17 AM

Thanks for the comment William,


Yes I realized that and I would suggest removing the .* from the first group since otherwise properties ending on "class" wont be accepted. I chose to stick to Struts2 proposed regex and notify them about the extra ".*"




on ‎05-12-2014 03:22 AM

Hi Reva,


Thanks for your comment. This filter is a temporal fix for this particular vulnerability. Struts 1 uses getParameterNames to loop through parameters that are going to be bound to ActionForm properties. So in order to mitigate this issue, it is enough to prevent dangerous property names from appearing in the return collection of getParameterNames(). Other request methods like getParameters are not intercepted by the filter and so those parameter will still be available for the servlets except that an ActionForm property mapping will be prevented.




Reva C
on ‎05-12-2014 05:19 AM

Hi Alvaro,


Can you give an example url parameter which will be prevented by this Filter? 



on ‎05-12-2014 05:25 AM

Hi Reva,


The one you posted is an example of a bean property that wont be bound to the actionForm, although a request.getParameters() will return it. The filter will prevent request.getParameterNames() but not request.getParameters(), effectively preventing ActionForm property binding but not other legitimate accesses to the request parameter.




on ‎05-12-2014 09:51 AM

I have been able to replicate the exploit when using a ActionForm directly, but not when using DynaActionForms. We are using DynaActionForms it appears to use form properties from the struts-config instead of the request.getParameterName during the ActionForm binding process. Is this correct?

on ‎05-12-2014 10:29 AM

Hi JFreedom,


Thanks for your comment. DynaActionForms use request.getParameterNames() in the same way that ActionForms do. But the bind process is slightly different, DynaActionForms contains a HashMap where the property name and value are stored instead of using apache commons BeanUtils to set up the beans properties.




Kristina T
on ‎05-13-2014 09:19 AM

Thanks so much for addressing this.


You responded to a comment that the regex given by Struts 2 is slightly incorrect, but I was unsure how to apply your comments.  You said to remove the .* from the first group, so would this change the regex to




or something else?  I was finding that in our application, with the original regex, we were able to set property names that ended in "class" just fine but were also able to deny setting those that would affect the class object directly, but I'm wondering if I'm missing something.  Can you please clarify?





on ‎05-13-2014 09:39 AM

Hi Kristina,


Thank you for your comment. The original regex suggested by the struts team is effectively equivalent to


That regex will match and prevent setting nested properties like:  somethingclass.prop

But it will allow setting a property like: simpleclass  (no nesting)


The regex that you suggest:


will allow to set nested and simple properties that end in "class" but will prevent the classloader manipulation.




on ‎05-15-2014 03:25 AM

Hello ,


Is this ok if I use below filter mapping in given solution.




Jamie Wang
on ‎05-15-2014 02:25 PM ‎05-16-2014 02:45 AM alvaro_munoz

Hi Alvaro,


I understand your comment about not able to detail how to verify the vulnerability. I am wondering if we can discuss this in private. I am working on a product where we need to verify if our product is vulnerable. Not sure if you can reach me via the email address I provided in the form or if possible, I can also be reached at xxx-xxx-xxxx. Thanks in advance.





on ‎05-16-2014 02:44 AM

Hi ushasingh,


That should work if all your actions use the .do suffix




on ‎05-16-2014 02:46 AM

Hi Jamie,


Im really sorry, but I cannot give any details on the exploit. Please get in contact with the Struts security team to see if they can help you.




on ‎06-02-2014 12:11 AM

 Hi Team,

       Thank you for your solution.

       But which name I need to configure in servlet-name

<servlet-name>YOUR ACTION SERVLET</servlet-name>
on ‎06-02-2014 01:03 AM



It depends on how do you name your Struts1 servlet. Look for a servlet definition like:




The servlet name for this particular example is "action".




on ‎06-06-2014 03:56 AM

Thanks for the solution.


I have a question though.


If my request has a parameter name like, would it not get filtered out as well? I am not good at regular expressions so not sure this regular expression filters only the malecious input parameters and not valid businessnames like myclass.something?




on ‎06-06-2014 04:01 AM

Hi Nilesh,


Thank you for your comment. The original regex suggested by the struts team will match and prevent setting nested properties like:  myclass.something

But it will allow setting a property like: myclass  (no nesting)


The following regex will allow to set nested and simple properties that end in "class" but will prevent the classloader manipulation.




on ‎06-16-2014 06:59 PM



Workarounds of cookie was necessary in Struts2.

In Struts1, is similar Workarounds unnecessary?




on ‎06-17-2014 01:40 AM

Hi Shigee,


No, this particular bug only affects Action Form bindings




Tomari Rohai
on ‎06-18-2014 07:16 AM

I've coded this, tested it, and I can see the bit of code that lets parameters through is being used, by examining the log.


So negatively, I can see this is working, no problemo.


How can I test a positive (ie, that somehing is being trapped by the code)? I dont want to know anything about the exploit, but I need a strategy whereby I can show this code is working.


Any ideas? Am I missing something glaringly obvious here? Me missing something obvious is always the default position.





on ‎06-18-2014 08:21 AM

Hi Tom,


Thanks for your comment. If the filter works ok and its correctly deployed, it should be preventing access to certain parameters. The parameters that are going to be intercepted are the ones in that match the regular expression. So for example if you have a Action form with a user field of type "User", then trying to set the nested property "user.class" should be trapped by the filter and logged.




Martin Gainty
on ‎07-09-2014 05:15 PM
1)You *should* see the parameters trapped by your regex with the System.out:
if (!parameterName.matches(regex)) { finalParameterNames.add(parameterName); System.out.println("Param included is : " + parameterName); }
else { System.out.println("Param excluded is : "+parameterName); }
2)Shark your line if you want to see the traffic coming and going

Saludos Cordiales desde EEUU,


on ‎09-03-2014 04:41 AM

Hi Alvaro,


Thanks for the post. Its very useful. Also, I'm having some queries. I would like to clear them out. 


1. Our application is based upon Spring Framework and is just using the struts tiles framework . So in our case we are having controllers instead of action forms. As we have imported struts 1.3.10 jars, so would like to know if our application comes under the scope of vulnerablility. 


2. Also, we are having a custom XSS filter already defined for all the URL's to find below patterns in parameter's.


Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
// Remove any lonesome <script ...> tag
Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// eval(...)
Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// expression(...)
Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// javascript:...
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
// vbscript:...
Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
// onload(...)=...
Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
//remove <IMG.. > tags
Pattern.compile("<IMG(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)


I would like to know if this servers the same purpose as the ParamFilter.


3. My last query is will Param Filter or above XSS filter prevent cookie attacks too?


on ‎12-15-2014 01:53 AM

Can we define a security policy and secure specific classes? Will this help in solving this?

on ‎12-29-2014 04:08 AM

I was able to recreate the issue (Struts 1.1) with url parameters (class.ClassLoader), which resulted in modifying the classloader settings. But could not see any issue with html elements with name class.ClassLoader. Is it sufficient if I only put parameter blacklisting in the filter?


Would like to know why the ParamWrapperFilter reads the input stream and check for blacklist pattern.

on ‎01-12-2015 01:46 AM



Parameter blacklistt should be used to protect query parameters and request body (so it is necessary to read and protect the request input stream)




on ‎01-15-2015 01:15 AM



I would like to know whether struts team will release the Struts1.3 version with this vulnerability been fixed ?


Thanks in advance.



on ‎01-21-2015 06:33 PM

Hi Support,


Any update for the my earlier query ?


In addition, Is this vulnerability impacted If my project is using the DynaActionForm ?


Please let me know in details.


Thks and Rgds



on ‎02-10-2015 01:22 AM

Hi support ,


We are using DynaActionForm in my project.


I would like to check with Struts support team to confirm whether the DynaActionForm is really impacted with this vulnerability.


Please let us know in details.


FYI. I have raised the same type of question last month and the question was not published yet into the portal.





on ‎02-10-2015 04:23 AM

Hi Feroz,


DynaActionForms are impacted but Im sorry we cannot disclose details.




on ‎02-18-2015 11:04 AM

Hi Alvaro,


I have applied filter using StrutsFilter1.jar from maven repository and modifying web.xml file by adding this:






















However, when I Analyze project using forify static analyzer it still flags Struts1Classloader issue.


Is that supposed to be?




on ‎02-19-2015 04:20 AM

Hi nvaslav48,


A bug has been filed and issue will be remove in future releases.




on ‎06-12-2015 11:15 AM



I would like to know if we have a solution to above discussed problem yet?




on ‎06-12-2015 11:17 AM



Also I am trying to Test the ParamWrapperFilter which was last updated on Jan 22. I am providing "][]Class][<>" as a value to parameterName, however pattern.matcher(parameterName).matches() line always returns false. Please can somebody explain me what I am doing wrong here.




on ‎06-12-2015 11:29 AM
Hi Sohil, Please file an issue in the github repo for further discussion. Thanks, A
on ‎06-15-2015 09:00 AM


Hi Alvaro,

As per your suggestion, I have posted issue in github repo. Please let me know if there is a fix for Classloader manipulation issue for Struts1.x.




‎06-15-2015 09:28 AM - edited ‎06-15-2015 09:29 AM

Hi Sohil,


I have just replied to your comment in github:


Also, please check for a different workaround that implies patching Struts 1 code or using an unofficial patched build:


Workaround: use patched struts distribution instead of this filter.

Patch link:

Patched struts 1.3.10 is available for example for Fedora 20 in build "struts-1.3.10-10.fc20" in form of RPM:

June 6 - 8, 2017
Las Vegas, Nevada
Discover 2017 Las Vegas
Join us for HPE Discover 2017 in Las Vegas. The event will be held at the Venetian | Palazzo from June 6-8, 2017.
Read more
Each Month in 2017
Software Expert Days - 2017
Join us online to talk directly with our Software experts during online Expert Days. Find information here about past, current, and upcoming Expert Da...
Read more
View all