|Home > Guides > Core Developers Guide > Security|
The Apache Struts 2 doesn't provide any security mechanism - it is just a pure web framework. Below are few tips you should consider during application development with the Apache Struts 2.
Config Browser Plugin exposes internal configuration and should be used only during development phase. If you must use it on production site, we strictly recommend restricting access to it - you can use Basic Authentication or any other security mechanism (e.g. Apache Shiro)
Very often access to different resources is controlled based on URL patterns, see snippet below. Because of that you cannot mix actions with different security levels in the same namespace. Always group actions in one namespace by security level.
You must always hide JSP file behind an action, you cannot allow for direct access to the JSP files as this can leads to unpredictable security vulnerabilities. You can achieve this by putting all your JSP files under the
WEB-INF folder - most of the JEE containers restrict access to files placed under the
WEB-INF folder. Second option is to add security constraint to the
The best approach is to used the both solutions.
devMode is a very useful option during development time, allowing for deep introspection and debugging into you app.
However, in production it exposes your application to be presenting too many informations on application's internals or to evaluating risky parameter expressions.
How to disable devMode in production
Please always disable
devMode before deploying your application to a production environment. While it is disabled by default, your struts.xml might include a line setting it to true. The best way is to ensure the following setting is applied to our struts.xml for production deployment:
<constant name="struts.devMode" value="false"/>
It's a good practice to reduce logging level from DEBUG to INFO or less. Framework's classes can produce a lot of logging entries which will pollute the log file. You can even set logging level to WARN for classes that belongs to the framework, see example Log4j2 configuration:
UTF-8 encoding when building an application with the Apache Struts 2, when using JSPs please add the following header to each JSP file
You should carefully design your actions without exposing anything via setters and getters, thus can leads to potential security vulnerabilities. Any action's setter can be used to set incoming untrusted user's value which can contain suspicious expression. Some Struts
Results automatically populate params based on values in
ValueStack (action in most cases is the root) which means incoming value will be evaluated as an expression during this process.
The Apache Struts 2 contains internal security manager which blocks access to particular classes and Java packages - it's a OGNL-wide mechanism which means it affects any aspect of the framework ie. incoming parameters, expressions used in JSPs, etc.
There are three options that can be used to configure excluded packages and classes:
struts.excludedClasses- comma-separated list of excluded classes
struts.excludedPackageNamePatterns- patterns used to exclude packages based on RegEx - this option is slower than simple string comparison but it's more flexible
struts.excludedPackageNames- comma-separated list of excluded packages, it is used with simple string comparison via
The defaults are as follow:
Any expression or target which evaluates to one of these will be blocked and you see a WARN in logs:
In that case
new MyBean() was used to create a new instance of class (inside JSP) - it's blocked because
target of such expression is evaluated to
It is possible to redefine the above constants in
struts.xml but try to avoid this and rather change design of your application!
Support for accessing static methods from expression will be disabled soon, please consider re-factoring your application to avoid further problems! Please check WW-4348.
This can impact actions which have large inheritance hierarchy and use the same method's name throughout the hierarchy, this was reported as an issue WW-4405. See the example below:
In such case OGNL cannot properly map which method to call when request is coming. This is do the OGNL limitation. To solve the problem don't use the same method's names through the hierarchy, you can simply change the action's method from
saveAction() and leaving annotation as is to allow call this action via
As from version 2.3.20 the framework provides two new interfaces which are used to accept / exclude param names and values - AcceptedPatternsChecker and ExcludedPatternsChecker with default implementations. These two interfaces are used by Parameters Interceptor and Cookie Interceptor to check if param can accepted or must be excluded. If you were using
excludeParams previously please compare patterns used by you with these provided by the framework in default implementation.
This mechanism was introduced in version 2.5. It allows control what methods can be accessed with the bang "!" operator via Dynamic Method Invocation. Please read more in Strict Method Invocation section of Action Configuration.