网站地图    收藏   

主页 > 后端 > 网站安全 >

Struts 2 Security Vulnerability - Dynamic Method Invocation

来源:自学PHP网    时间:2015-04-17 13:03 作者: 阅读:

[导读] IntroductionThe Struts 2 web application framework has a long-standing security vulnerability that may not be well known to new Struts 2 developers. By default the framewo......

Introduction

The Struts 2 web application framework has a long-standing security vulnerability that may not be well known to new Struts 2 developers. By default the framework enables a technique called dynamic method invocation. This technique allows a developer to specify in a Struts 2 action url what method should be called in the Action class. The security problem is that any user of the Struts 2 web application can also use dynamic method invocation to call a public method that is in the Action class. The purpose of this article is to explain the vulnerability and how to fix it. Note this problem occurs through the Struts 2.2.1.1 release, which is the latest release as of February 2011.

 

 

Please note that this security issue is well-known to most experienced Struts 2 developers and to the Struts 2 framework committers. They are working on a permanent fix in a future Struts 2 release. You can learn more about this vulnerability and its fix by searching the Struts 2 developers mailing list. My goal with this article is to better inform new Struts 2 developers about this vulnerability and how to prevent it.

NOTE: With the release of Struts 2.3.1.1 in December 2011, the security issue with using dynamic method invocation was addressed.  However, by default even in version 2.3.1.1, the vulnerability exists and developers must add additional markup to their package statement to prevent users being able to execute public methods.  See http://struts.apache.org/2.3.1/docs/action-configuration.html#ActionConfiguration-DynamicMethodInvocation for more detail.

Dynamic Method Invocation

In Struts 2, you can use the bang (!) operator to specify which method should be executed in the Action class. For example, let's say I have an action named recoverpassword that is mapped to class RecoverPassword. In class RecoverPassword is public method getUserPassword. I can use the bang operator to tell the Struts 2 framework to execute method getUserPassword when action recoverpassword is specified in the URL. I can do this by constructing the URL as follows:

http://localhost:8080/mywebapp/recoverpassword!getUserPassword.action

The part after the bang operator is the method Struts 2 should execute in the class associated with the recoverpassword action.

Note that method getUserPassword must be public and have no parameters. In Struts 2, by default, dynamic method invocation is allowed. Any user of the web application can play around with calling your application's URLs trying to get Struts 2 to execute a method.

For more information about  dynamic method invocation see: http://struts.apache.org/2.2.1.1/docs/action-configuration.html#ActionConfiguration-DynamicMethodInvocation.

Example Application

To help illustrate the vulnerability, I've created a simple example application which you can download or view here:

http://www.bpjava.net/struts2_security_vulnerability/

You can download the example project, named Struts2_Security_Vulnerability_Example. The project was created using Eclipse 3.6 and Maven. It is a standard Maven project so if you don't have Eclipse, you should be able to import the unzipped project into any Java IDE that supports Maven.

To build the application's war file run mvn clean package from the project's root folder. The war file is created in the target sub-folder. Copy the war file to your Servlet container (e.g. Tomcat, GlassFish) and  then startup the Servlet container.

In a web browser go to: 

http://localhost:8080/struts2_security_vulnerability/index.action 
(note for this URL and the others that follow if you want to use the example application I deployed to my own server, replace localhost:8080 in the URL with www.bpjava.net - for examplehttp://www.bpjava.net/struts2_security_vulnerability/index.action).

You should see a web page with Welcome to Struts 2!

Security Vulnerability Caused By Dynamic Method Invocation

  The Action class RecoverPassword has a public method called getPassword and the project has not disabled dynamic method invocation. So a user entering this URL  in the browser:

http://localhost:8080/struts2_security_vulnerability/recoverpassword!getPassword.action

will see the String returned by the method getPassword.  Note that recoverpassword must be matched to an Action class that has a public getPassword method that has no parameters.

The result of the url:

http://localhost:8080/struts2_security_vulnerability/recoverpassword!getPassword.action

will either be a 404 error or a stack trace if the struts devmode property is true. The 404 error page will include this line:

No result defined for action edu.ku.it.si.struts2securityvulnerability.security.action.RecoverPassword  and result user_secrect_password

The last part above is the String returned by method getPassword, which in this  example is the user's password. The stack trace will include a similar line that exposes the user's password.

Any public method in the Action class that has no parameters is vulnerable, even  if the method returns no value.  For example enter this URL in the example application:

http://localhost:8080/struts2_security_vulnerability/changepassword!changePassword.action?newPassword=my_new_password&username=bruce

You will not see anything in the browser after the URL executes, but the above URL will cause method changePassword to be executed (see class ChangePassword ) and the password for user bruce will be changed to my_new_password.  This URL completely bypasses the authentication check in the execute method of  class ChangePassword. (To verify that method changePassword was called see the console output after executing the above URL.)

How To Fix The Dynamic Method Invocation Security Vulnerability

Include in struts.xml this Struts 2 property setting:

<constant name="struts.enable.DynamicMethodInvocation" value="false" />

or in struts.properties:

struts.enable.DynamicMethodInvocation = false

or in web.xml include this init-param node in the Struts 2 filter:



<init-param>
<param-name>struts.enable.DynamicMethodInvocation</param-name>
<param-value>false</param-value>
</init-param>

 

In the example application's struts.xml uncomment that property setting to fix the problem in the example.

The above setting will prevent Struts 2 from parsing the bang operator (!) in the URL, so then the whole part before .action will be used to match to a configured Struts 2 action. 

For example with this URL

http://www.2cto.com /struts2_security_vulnerability/recoverpassword!getPassword.action

instead of method getPassword being called on the Action class matched to action recoverpassword, the  Struts 2 framework will try to find an action named "recoverpassword!getPassword" (which won't exist).

Other Good Practices To Follow When Designing Struts 2 Action classes

1.  The only methods in the Action class that should be public are the those methods specifically matched to a Struts 2 action (e.g. execute, input) and get/set methods for the instance fields  that are exposed to the view pages.

2.  All methods that do some work on behalf of the action should be in a Service layer class and not in the  ActionSupport class.

Summary

Hopefully this article will convince Struts 2 developers to always include setting the DynamicMethodInvocation property to false to prevent the use of the bang operator to call specific methods in the Action class

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论