This article was originally published on the Red Hat Customer Portal. The information may no longer be current.

Overview

The Java Enterprise Edition (EE) 7 specification introduced a new feature which allows application developers to specify a Java Security Manager (JSM) policy for their Java EE applications, when deployed to a compliant Java EE Application Server such as JBoss Enterprise Application Platform (EAP) 7.1. Until now, writing JSM policies has been pretty tedious, and running with JSM was not recommended because it adversely affected performance. Now a new tool has been developed which allows the generation of a JSM policy for deployments running on JBoss EAP 7.1. It is possible that running with JSM enabled will still affect performance, but JEP 232 indicates the performance impact would be 10-15% (it is still recommended to test the impact per application).

Why Run with the Java Security Manager Enabled?

Running a JSM will not fully protect the server from malicious features of untrusted code. It does, however, offer another layer of protection which can help reduce the impact of serious security vulnerabilities, such as deserialization attacks. For example, most of the recent attacks against Jackson Databind rely on making a Socket connection to an attacker-controlled JNDI Server to load malicious code. This article provides information on how this issue potentially affects an application written for JBoss EAP 7.1. The Security Manager could block the socket creation, and potentially thwart the attack.

How to generate a Java Security Manager Policy

Prerequisites

  • Java EE EAR or WAR file to add policies to;
  • Targeting JBoss EAP 7.1 or later;
  • Comprehensive test plan which exercises every "normal" function of the application.

If a comprehensive test plan isn't available, a policy could be generated in a production environment, as long as some extra disk space for logging is available and there is confidence the security of the application is not going to be compromised while generating policies.

Setup 'Log Only' mode for the Security Manager

JBoss EAP 7.1 added a new feature to its custom Security Manager that is enabled by setting the org.wildfly.security.manager.log-only System Property to true.

For example, if running in stand-alone mode on Linux, enable the Security Manager and set the system property in the bin/standalone.conf file using:

SECMGR="true"
JAVA_OPTS="$JAVA_OPTS -Dorg.wildfly.security.manager.log-only=true"

We'll also need to add some additional logging for the log-only property to work, so go ahead and adjust the logging categories to set org.wildfly.security.access to DEBUG, as per the documentation, e.g.:

/subsystem=logging/logger=org.wildfly.security.access:add
/subsystem=logging/logger=org.wildfly.security.access:write-attribute(name=level,value=DEBUG)

Test the application to generate policy violations

For this example we'll use the batch-processing quickstart. Follow the README to deploy the application and access it running on the application server at http://localhost:8080/batch-processing. Click the 'Generate a new file and start import job' button in the Web UI and notice some policy violations are logged to the $JBOSS_HOME/standalone/log/server.log file, for example:

DEBUG [org.wildfly.security.access] (Batch Thread - 1) Permission check failed (permission "("java.util.PropertyPermission" "java.io.tmpdir" "read")" in code source 
"(vfs:/content/batch-processing.war/WEB-INF/classes <no signer certificates>)" of "ModuleClassLoader for Module "deployment.batch-processing.war" from Service Module Loader")

Generate a policy file for the application

Checkout the source code for the wildfly-policygen project written by Red Hat Product Security.

git clone git@github.com:jasinner/wildfly-policygen.git

Set the location of the server.log file which contains the generated security violations in the build.gradle script, i.e.:

task runScript (dependsOn: 'classes', type: JavaExec) {
    main = 'com.redhat.prodsec.eap.EntryPoint'
    classpath = sourceSets.main.runtimeClasspath
    args '/home/jshepher/products/eap/7.1.0/standalone/log/server.log'
}

Run wildfly-policygen using gradle, i.e.:

gradle runScript

permissions.xml file should be generated in the current directory. Using the example application, the file is called batch-processing.war.permissions.xml. Copy that file to src/main/webapp/META-INF/permissions.xml, build, and redeploy the application, for example:

cp batch-processing.war.permissions.xml $APP_HOME/src/main/webapp/META-INF/permissions.xml

Where APP_HOME is an environment variable pointing to the batch-processing application's home directory.

Run with the security manager in enforcing mode

Recall that we set the org.wildfly.security.manager.log-only system property in order to log permission violations. Remove that system property or set it to false in order to enforce the JSM policy that's been added to the deployment. Once that line has been changed or removed from bin/standalone.conf, restart the application server, build, and redeploy the application.

JAVA_OPTS="$JAVA_OPTS -Dorg.wildfly.security.manager.log-only=false"

Also go ahead and remove the extra logging category that was added previously using the CLI, e.g.:

/subsystem=logging/logger=org.wildfly.security.access:remove

This time there shouldn't be any permission violations logged in the server.log file. To verify the Security Manager is still enabled look for this message in the server.log file:

INFO  [org.jboss.as] (MSC service thread 1-8) WFLYSRV0235: Security Manager is enabled

Conclusion

While the Java Security Manager will not prevent all security vulnerabilities possible against an application deployed to JBoss EAP 7.1, it will add another layer of protection, which could mitigate the impact of serious security vulnerabilities such as deserialization attacks against Jackson Databind. If running with Security Manager enabled, be sure to check the impact on the performance of the application to make sure it's within acceptable limits. Finally, use of the wildfly-policygen tool is not officially supported by Red Hat, however issues can be raised for the project in Github, or reach out to Red Hat Product Security for usage help by emailing secalert@redhat.com.


Über den Autor

Specializing in Kubernetes, container runtimes, and web applications, Jason Shepherd is a principal security engineer in Red Hat's Product Security team. With a passion for open source and dedication to client success, Shepherd is your go-to guy for security assessment and data for security audits.

Read full bio