SlideShare a Scribd company logo
@spoole167
7 Perilous Pitfalls with Java 2020
@spoole167
This Session is about Java
security
• It’s about how to start thinking
about secure application design
• It’s about how to improve your
development processes
• It’s about why this really matters
• It’s a taster only
There’s not much Java in it..
@spoole167
Software design flaws are grouped into “7 Pernicious Kingdoms”
@spoole167
A bit of a marketing
exercise
• 2005 Fortify Software released a
paper called
“Seven Pernicious Kingdoms: A
Taxonomy of Software Security
Errors”
• It caught on among the security
community
@spoole167
In fact there are more than 7
☺
@spoole167
Seven
Pernicious
Kingdoms
Security Features
Time and State
Errors
Input Validation and Representation
API Abuse
Code Quality
Encapsulation
Environment
@spoole167
Seven
Perilous
Pitfalls
For Java
Security Features
Time and State
Errors
Input Validation and Representation
API Abuse
Code Quality
Encapsulation
Environment
@spoole167
Agenda
Using real scenarios
and other examples
dip into the 7PK
looking at code and
thinking about design
@spoole1679
Pitfall 0 :Believing the fake
news…
@spoole167
All You need is a firewall
@spoole167
Internet
network
cluster
Server
Container……………………application
Reality
Do you think just a firewall is sufficient?
@spoole167
Internet
network
cluster
Server
Container……………………application
Reality
Bad guys are looking for exploits
everywhere
Vulnerabilities in the application
Vulnerabilities in the container
Vulnerabilities in the server
Vulnerabilities in the cluster
Vulnerabilities in the network
@spoole167
Internet
network
cluster
Server
Container……………………application
Reality
Your best defense
✓ Defense in depth
✓ Detection
Forsooth we
are under
attack my
liege
@spoole167
First scenario
• I’m developing a performance tool for
Adopt OpenJDK
• It’s designed to run locally but will
eventually be hostable
@spoole167
Plimsoll
@spoole167
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
@spoole167
Problems caused by metacharacters, alternate encodings and
numeric representations. General security problems result from
trusting input.
Input Validation and Representation
@spoole167
Input Validation and Representation
Forms Input.
1. Browser javascript code validates the form
2. Send the data to the server over a websocket as JSON.
3. Server turns JSON into Java
Browser Server
WS
http
@spoole167
Input Validation and Representation
My application only expects local war files to be loaded…
‘file://dir/app.war’
@spoole167
Input Validation and Representation
My application only expects local war files to be loaded…
‘http://badserver.com/badapp.war’
What happens if I get this?
@spoole167
Input Validation and Representation
Pretty obviously you cannot ever
trust what a client sends you. Ever.
Browser Server
@spoole167
Input from an end point is an obvious place to be cautious
Think of it like this…
Every API you write OR call. Whether REST interface or a simple class. Is
a ‘contract’
If that contract is not explicit and enforced your code is vulnerable.
Input Validation and Representation “It is the callers responsibility”
@spoole167
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Input Validation and Representation
Adopt Server
http
My tool uses the docker command line interface to retrieve information and run containers
“docker images”
“docker run –it ubuntu /bin/bash”
@spoole167
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
Path to the docker exe
Where to put the output
@spoole167
Input Validation and Representation
Driver driver = new Driver();
…
List l = driver.run(“ps –a”);
if (driver.hasError() == false) {
System.out.println(l);
}
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
Input Validation and Representation
Driver driver = new Driver();
…
List l = driver.run(“ps –a”);
if (driver.hasError() == false) {
System.out.println(l);
}
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
What’s wrong with this code?
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
This field is never validated.
Does it really point to a docker executable?
What would happen if it was set to some
other executable?
Could simply run a version check on it!
“docker –version”
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
Even if the field was validated
during construction it can still be
changed afterwards.
Relying on constructor validation
only is also poor practise.
(Re)validate before usage
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
What about this field?
Set to “/tmp/docker.out” ?
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
What validation does
Java.io.File do?
Input Validation and Representation
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
@spoole167
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
private static final FileSystem fs = DefaultFileSystem.getFileSystem();
“A normal Win32 pathname contains no duplicate slashes,
except possibly for a UNC prefix, and does not end with a slash.
It may be the empty string. Normalized Win32 pathnames have
the convenient property that the length of the prefix almost
uniquely identifies the type of the path and whether it is
absolute or relative”
What validation does
Java.io.File do?
- Not much!
@spoole167
File f=new File("../../../../../../../../../../../../../../../../etc/passwd");
System.out.println(f);
Path p=f.toPath();
System.out.println(p);
Path q=p.toRealPath(LinkOption.NOFOLLOW_LINKS);
System.out.println(q);
../../../../../../../../../../../../../../../../etc/passwd
../../../../../../../../../../../../../../../../etc/passwd
/etc/passwd
Code
Output
Takeaway Validation is always your problem
Input Validation and Representation
@spoole167
Input Validation and Representation
Who uses Java serialization?
@spoole167
Input Validation and Representation
Who uses Java serialization?
Do you use RMI, JMX, JMS, Spring Service Invokers?
@spoole167
XMLEncoder (XML)
XStream (XML/JSON/various)
Kryo (binary)
Hessian/Burlap (binary/XML)
Castor (XML)
json-io (JSON)
Jackson (JSON)
Fastjson (JSON)
Red5 IO AMF (AMF)
Apache Flex BlazeDS (AMF)
Flamingo AMF (AMF)
GraniteDS (AMF)
WebORB for Java (AMF)
SnakeYAML (YAML)
jYAML (YAML)
YamlBeans (YAML)
Input Validation and Representation
How about one of these?
@spoole167
Input Validation and Representation
Any place you rely on:
persistence, messaging, remote ejb
rmi / jmx , rmi-iiop, CDI
There’s some form of serialization going on.
@spoole167
public class LayerCake {
private int layers;
public LayerCake(int layers) {
if(layers<1 || layers > 3)
throw new IllegalArgumentException("number of layers is invalid");
this.layers=layers;
}
Constructors do not get called
During deserialisation
So I can make this value anything I want
What the bad guys do
@spoole167
Input Validation and Representation
https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet
What the good and bad guys do
What the bad guys do
What the bad guys do
@spoole167
With serialisation vulnerabilities I
may be able to get the code to
overwrite a critical file somewhere
else.
If I modify both the exe and file
fields I can control what data gets
written to your system
What the bad guys do
public class Driver {
private static final String DEFAULT_EXEC = "/usr/local/bin/docker";
private boolean error;
private String docker;
private File outputFile;
private List results=new LinkedList();
public Driver() {
this(DEFAULT_EXEC);
}
public Driver(String driver) {
docker = driver;
outputFile = new File("/tmp/docker.out");
}
Remember, constructors are not
called during deserialization. The
data is simply inserted.
@spoole167
Protecting yourself
against serialization
exploits is hard
And remember – it’s not
just your code.
Its all your dependencies
too!
Another talk
@spoole167
#1: all data received must be considered
untrusted and potentially dangerous.
• Data means anything that
comes in – command lines,
env variables, sockets, GUI,
REST , even data coming
from your own server…
• You must never trust the
systems who send you data.
• You can almost never trust
the systems you retrieve
data from
• You must validate data
when you get it AND before
you use it
Input Validation and Representation
@spoole167
Using an API in a manner contrary to its intended use
API Abuse
@spoole167
API Abuse
My tool tags all the
containers it creates with
“adoptopenjdk=true”
That makes it easier to
retrieve only the relevant
containers when talking to
docker.
I have a test to check I can
create such containers
String id = createSimpleContainer(TEST_IMAGE_NAME);
ContainerInfo ci=inspectContainer(id);
assertTrue(ci.labels().containsKey(“adoptopenjdk”);
@spoole167
API Abuse
But I want to make sure
that the calls to docker are
really working.
So I have a ‘get all’ method.
It’s not used in production
But its exposed as a test
end point…
String id = createSimpleContainer(TEST_IMAGE_NAME);
List<Container> allc = allContainerList();
assertTrue(allc.isEmpty()==false);
get("/test/v1/*" , (req, res) ->plimsoll.test_v1_request.handleRequest(req,res));
@spoole167
API Abuse
A common vulnerability pattern is to find hidden end points like ones just for
testing.
Reading the code on github or just Googling for your sites metadata can easily
reveal them
And of course test end points tend to have less security 
Never have APIs that are just for ‘testing’ or bypass normal
authentication processes..
@spoole167
Google search: intitle:index.of WEB-INF
I found something…
What the bad guys do
@spoole167
<servlet>
<servlet-name>TestRetrieveFileResponseServlet</servlet-name>
<display-name>TestRetrieveFileResponseServlet</display-name>
<servlet-
class>tests.webservices.TestRetrieveFileResponseServlet</servlet-class>
</servlet>
servlet-mapping>
<servlet-name>TestRetrieveFileResponseServlet</servlet-name>
<url-pattern>/TestRetrieveFileResponseServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
So I called it
What the bad guys do
@spoole167
API Abuse
My tool allows for complex scenarios to be created.
JVM = Hotspot or OpenJ9
App Server = Tomcat or Jetty
Various versions strings.
The combinations are sent one by one…
JVM=Hotspot, AppServer=Tomcat, AppVersion=9.0
@spoole167
API Abuse
The code validates the entries as being
individually
correct..
✓ JVM=Hotspot
✓ AppServer=Tomcat
✓ AppVersion=9.4.9
But not that the combinations are valid!
@spoole167
API Abuse
My code also returns lists of containers so there
are page / page size type parameters..
“list containers from page 7 with page size 100”
“list containers from page 1 with page size 10”
@spoole167
API Abuse
My code also returns lists of containers so there
are page / page size type parameters..
“list containers from page 7 with page size 100”
“list containers from page 1 with page size 10”
What about..
“list containers from page 0 with page size -100”
“list containers from page -1 with page size 10”
“list containers from page MAX_INT with page size -MAX_INT”
55
Try likely entry points and all the http verbs
GET /users/1
DELETE /api/v1/users/1
OPTIONS /api/v1/user/1
HEAD /api/v1/user/1
POST /users/1
What the bad guys do
56
Play with the headers and cookies
POST /api/v1/user HTTP/1.1
Host: developer.mozilla.org
Content-Length: 64
Content-Type: application/x-
www-form-urlencoded
What the bad guys do
57
Can I get the service to fail or break?
404 “Not Found”
503 “Service Unavailable”
“500 Internal Server Error”
Different errors from different components?
What the bad guys do
58
If I can find a static endpoint
service I might be able to get
at the filesystem…
GET /api/v1/images/a/../../../../../../etc/passwd
What the bad guys do
59
Fuzzing calls and data..
GET /users/1
POST /users/2
PUT /users/20000?name=“(select
GET /users/-1
GET /users/$INT_MAX
What the bad guys do
60
What the bad guys do
61
Fuzzing calls and data.
Fuzz urls, json payloads, xml payloads, binary payloads …
Import / export / upload / download options ..
Command line options, file formats …
“known-to-be-dangerous” values
In the public domain
Widespread
& mature
Automatic ‘protocol’
detection & exploitation
What the bad guys do
@spoole167
#2 Never give control to the
caller by accepting
unconstrained instructions
• Calling endpoints that are
hidden
• Finding hidden fields in your
requests and changing them
• Sending unexpected but
pseudo-valid combinations of
data
• Exploring the data ranges (+
and - )
• Using an API out of context.
(like credit card validation)
• Exploiting query languages
(SQL injection plus. JQ, or
Xpath etc)
• most systems assume any call
to it is correct and do minimal
validation once the individual
elements are accepted.
API Abuse
@spoole167
Errors
Errors related to error handling
@spoole167
Errors
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
File f = new File("plimsoll.properties");
if (f.exists()) {
FileReader fr;
try {
fr = new FileReader(f);
p.load(fr);
fr.close();
} catch (IOException e) {
}
return p;
}
Some code – reads a
config file…
@spoole167
Errors
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
File f = new File("plimsoll.properties");
if (f.exists()) {
FileReader fr;
try {
fr = new FileReader(f);
p.load(fr);
fr.close();
} catch (IOException e) {
}
return p;
}
Don’t assume that only
the errors you expect will
occur - such as
FileNotFoundException
@spoole167
Errors
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
File f = new File("plimsoll.properties");
if (f.exists()) {
FileReader fr;
try {
fr = new FileReader(f);
p.load(fr);
fr.close();
} catch (FileNotFoundException e) {
// allowed
} catch (IOException e) {
// not expected
}
return p;
}
Better!
@spoole167
Errors
Catching or throwing exceptions in a more generic manner than needed can hide
the activities of the attacker
Either because of a lack of specific info in logging and log analysis
i.e: “Config file not found”. Vs “Unexpected IO Error reading the config file”
Or simply because the unusual exception is treated as usual
@spoole167
Errors
Catching or throwing exceptions in a more generic manner than needed can hide
the activities of the attacker
Either because of a lack of specific info in logging and log analysis
i.e: “Config file not found”. Vs “Unexpected IO Error reading the config file”
Or simply because the unusual exception is treated as usual
BTW - catching NullPointer Exceptions as a way of detecting ‘expected’ nulls is also
poor practice – as described above. You simply can’t tell which NPE is which.
@spoole167
More Code
Errors
@spoole167
<account>
<name>
Mega Corp Limited
</name>
<address>
The Citadel
London
SW1
</address>
<balance amount="100" currency="EURO"/>
</account>
You have some XML
@spoole167
<account>
<name>
Mega Corp Limited
</name>
<address>
The Citadel
London
SW1
</address>
<balance amount="100"
currency="EURO"/>
</account>
{
name: "Mega Corp Limited",
address : {
line1: "The Citadel",
city: "London",
postcode: "SW1"
},
balance: {
amount: 100,
currency: "EURO"
}
}
Which you have to convert to JSON
@spoole167
JsonObject jo=new JsonObject();
for(int i=0;i<l.getLength();i++) {
Node n= l.item(i);
switch( n.getNodeName() ) {
case "address" : jo.add(parseAddress(n)); break;
case "name" : jo.add(parseName(n)); break;
case "balance" : jo.add(parseBalance(n)); break;
}
}
You write some code
@spoole167
<account>
<name>
Mega Corp Limited
</name>
<address>
The Citadel
London
SW1
</address>
<balance amount="100" currency="EURO"/>
<overdraft limit=”500" />
</account>
And then the XML changes
@spoole167
JsonObject jo=new JsonObject();
for(int i=0;i<l.getLength();i++) {
Node n= l.item(i);
switch( n.getNodeName() ) {
case "address" : jo.add(parseAddress(n)); break;
case "name" : jo.add(parseName(n)); break;
case "balance" : jo.add(parseBalance(n)); break;
case ”overdraft": jo.add(parseOverdraft(n)); break;
}
}
So you have to change your code
@spoole167
This happens a lot<account>
<name>
Mega Corp Limited
</name>
<address>
The Citadel
London
SW1
</address>
<balance amount="100" currency="EURO"/>
<overdraft limit=”500" />
<credit>Low</credit>
</account>
@spoole167
String handlerName = handlers.getProperty(n.getNodeName().toLowerCase());
try {
Class c = Class.forName(handlerName);
IHandler handler = (IHandler) c.newInstance();
jo.add(handler.convert(handler));
} catch (Exception e) {
String errorInfo = "could not create class for handler" + n.getNodeName() + " class=" + handlerName;
throw new IOException(errorInfo, e);
}
}
private static Properties handlers = new
Properties(file,System.getProperties());
You change your code
address=com.foo.standard.AddressHandler
balance=com.foo.standard.BalanceHandler
name=com.foo.standard.NameHandler
@spoole167
-Dtesthandler=com.foo.standard.CreditHandler
Now you can easily add
Easy to update and test
@spoole167
And when things go wrong you get a nice error message
java.io.IOException: could not create class for handler credit
class=null
String errorInfo = "could not create class for handler" + n.getNodeName() +
"class=" + handlerName;
throw new IOException(errorInfo, e);
Missing handler in the properties file
@spoole167
And when things go wrong you get a nice error message
java.io.IOException: could not create class for handler credit
class=com.foo.handler.CreditHandler
String errorInfo = "could not create class for handler" + n.getNodeName() +
"class=" + handlerName;
throw new IOException(errorInfo, e);
Missing class on the classpath
@spoole167
What happens with this data?
<account>
<name>
Mega Corp Limited
</name>
<address>
The Citadel
London
SW1
</address>
<balance amount="100" currency="EURO"/>
<java.ext.dirs/>
</account>
What the bad guys do
@spoole167
String errorInfo = "could not create class for handler" + n.getNodeName() +
"class=" + handlerName;
throw new IOException(errorInfo, e);
java.io.IOException: could not create class for handler java.ext.dirs class
=/Users/spoole/Library/Java/Extensions:
/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/ext:
/Library/Java/Extensions:/Network/Library/Java/Extensions:
/System/Library/Java/Extensions:
/usr/lib/java
What the bad guys do
82
Stack traces and error messages really help
More help I’m on the right track
More component info
What the bad guys do
@spoole167
Google search: intitle:Error Page pageWrapper.jsp?
I found something…
What the bad guys do
@spoole167
java.lang.NullPointerException at com.stoneware.server.auth.OpenIDProviders.getProviderFromUrl(qx:91) at
org.apache.jsp.openid.openIDClaim_jsp._jspService(openIDClaim_jsp.java:248) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) at
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) at
org.eclipse.jetty.jsp.JettyJspServlet.service(JettyJspServlet.java:107) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at
org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) at com.stoneware.filter.VersionCheckFilter.doFilter(wtb:391) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.filter.SecurityFilter.doFilter(sed:802) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.relay.b.A.doFilter(tlc:1671) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.filter.SessionIDFilter.doFilter(bvb:1475) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.relay.managers.f.doFilter(or:500) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at
org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224) at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:542) at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) at
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) at
org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at
org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:332) at org.eclipse.jetty.servlets.gzip.GzipHandler.handle(GzipHandler.java:479)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at
org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95) at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at
com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:190) at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:499) at
org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) at
org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) at
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Unknown Source)
Error traces can be used to identify what you’re running –
down to working out the version number…
What the bad guys do
85
Log / alert unexpected behavior
✓ Build in an expectation of what the client will be doing with
the data.
✓ All log entries must be useful – generic errors don’t help.
✓ Be careful about the amount of extra info in a log –
remember the bad guys may gain access to them too
Following good API design doesn’t mean you have to be too helpful.
Errors
@spoole167
#3 Error paths are as critical as normal flows
#4 Report only enough information to
identify the situation
• In general we’re poor at
dealing with errors in our
code.
• Developers focus on the
positive side.
• With consequential lack of
testing for error paths and
checking correct behavior
Errors
@spoole167
Security Features
Authentication, access control, confidentiality, cryptography, privilege management.
@spoole167
Can you rely on having a secure encrypted connection?
Browser Exploit Against
SSL/TLS (BEAST)
Compression
Ratio Info-leak
Made Easy
(CRIME)
Browser Reconnaissance and
Exfiltration via Adaptive
Compression of Hypertext
(BREACH)
Padding Oracle On Downgraded
Legacy Encryption (POODLE)
What the bad guys do
@spoole167
All data to and from the API is public
Even if you have a secure connection to the client
Man in the middle Reverse
engineered
client or app
Malware / xss
In the browser
What the bad guys do
90
Read the logs
What the bad guys do
@spoole167
Phew.
• So many things ways your
application can be
vulnerable.
• Security is not something
you add after. It’s always a
part of your design thinking.
@spoole167
Security Features
“I don’t need any security as the
system is local…”
“I’ll add security later”
“I’m not sure what security means”
@spoole167
Security Features
Many vulnerabilities come from poor authentication and access control
methods but ‘Security’ is a wider topic.
Confidentiality : Managing the data in your care
Cryptography : methods to ensure information is kept private
Privilege management: Ensuring actors are who they say they are
@spoole167
“I don’t need any security as the system is local…”
Security Features
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
@spoole167
“I don’t need any security as the system is local…”
Security Features
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
The browser is vulnerable to Cross Site Scripting attacks. So a remote attacker could get on to your system
@spoole167
“I don’t need any security as the system is local…”
Security Features
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
Since my tool uses an API that is unconstrained (ie the command line). The attacker could do anything
And the tool is downloading and running code from the web – another attack point
@spoole167
“I don’t need any security as the system is local…”
Security Features
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
The docker instance may have access to a secure repository. Without security my tool is enabling an easy bypass of
any access controls. The contents of the server are now available for a hacker to explore or use.
@spoole167
“I don’t need any security as the system is local…”
Security Features
Browser Server
Docker
Daemon
Remote
repositories
Local
repositories
WS
Cmd line
http
Adopt Server
http
So actually my tool needs really good security features.
@spoole167
Security Features
A few examples of vulnerable designs
@spoole167
Security Features
Trusting the end user not to tamper with the data
Cookie[] cookies =
request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("role")) {
userRole = c.getValue();
}
}
@spoole167
Security Features
Trusting the end user not to tamper with the data
Cookie[] cookies =
request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("role")) {
userRole = c.getValue();
}
}
Does encryption solve this?
@spoole167
Security Features
Trusting the end user not to tamper with the data
Cookie[] cookies =
request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("role")) {
userRole = c.getValue();
}
}
No!
XSS attacks often replace encrypted
cookies etc with ones from another
session that has the required
privileges.
You must have additional privilege
management processes in play
@spoole167
Security Features
Having endpoints that allows the
client to read the config
get: ”/api/v1/config/<key_name>”.
Returns json :
{ “key”: key_name , “value” : value }
public String getConfigValue(String key) {
return config.getProperty(key);
}
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
..
Poor confidentiality management
@spoole167
Security Features
My code has a endpoint that allows the
client to read the config
get: ”/api/v1/config/<key_name>”.
Returns json :
{ “key”: key_name , “value” : value }
public String getConfigValue(String key) {
return config.getProperty(key);
}
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
..
Poor confidentiality management
Since the config was backed by
System.getProperties all system
properties are exposed..
@spoole167
Google search: intitle:index.of WEB-INF
I found something…
What the bad guys do
@spoole167
<servlet-mapping>
<servlet-name>PingPage</servlet-name>
<url-pattern>/status</url-pattern>
</servlet-mapping>
I found this
So I called it
What the bad guys do
@spoole167
What the bad guys do
@spoole167
Another Google search:
inurl:”8080/jmx-console”
This dork will list all unauthenticated jboss servers
with jmx-console access.
I found something…
What the bad guys do
@spoole167
private Properties loadConfig() {
Properties p = new Properties( System.getProperties() );
File f = new File("plimsoll.properties");
if (f.exists()) {
FileReader fr;
try {
fr = new FileReader(f);
p.load(fr);
fr.close();
} catch (IOException e) {
}
return p;
}
Security Features
Unsophisticated credentials management
-Ddocker.user=foo -Ddocker.password=bar.
Storing information
In text files. Easily
readable.
Easily changed
on the command line.
(turns up in the logs)
@spoole167
Yet another Google search:
filetype:password jmxremote
I found something…
#
# Following are two commented-out entries. The
"measureRole" role has
# password "QED". The "controlRole" role has password
"R&D".
#
monitorRole C0gnitive!
controlRole C0gnitive!
What the bad guys do
@spoole167
Security Features
Unsophisticated credentials management
That end up in your git repo…
Q: Can you easily remove password data from your
repo once committed?
@spoole167
Security Features
Unsophisticated credentials management
That end up in your git repo…
A: these people seem to think so..
@spoole167
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
public boolean isClientTrusted( X509Certificate[] cert) {
return true;
}
public boolean isServerTrusted( X509Certificate[] cert) {
return true;
}
}}
Security Features
Deliberate weakening of security
protocols
@spoole167
Github search “implements TrustManager”
I found something…
What the bad guys do
@spoole167We’ve found 72,609 code results
AlwaysValidTrustManager
TrustAllServersWrappingTrustManager
A very friendly, accepting trust
manager factory. Allows anything
through. all kind of certificates are
accepted and trusted.
A very trusting trust manager that
accepts anything
// Install the all-trusting trust
manager
OverTrustingTrustProvider
AllTrustingSecurityManagerPlugin.java
AcceptingTrustManagerFactory.java
AllTrustingCertHttpRequester.java
Security Features
@spoole167We’ve found 72,609 code results
AlwaysValidTrustManager
TrustAllServersWrappingTrustManager
A very friendly, accepting trust
manager factory. Allows anything
through. all kind of certificates are
accepted and trusted.
A very trusting trust manager that
accepts anything
// Install the all-trusting trust
manager
OverTrustingTrustProvider
AllTrustingSecurityManagerPlugin.java
AcceptingTrustManagerFactory.java
AllTrustingCertHttpRequester.java
Security Features
How many are in your
dependencies?
@spoole167
Security Features
Defaulting to full access or running too much under privilege
method() {
AccessController.doPrivileged( new PrivilegedAction())
{
public Object run() {
// my app goes here
}
};
}
@spoole167
#5 Access controls as near to business logic as possible
#6 Keep credentials encrypted, safe and out of memory
#7 Fail safely
#8 Know your responsibilities for others
• For many the word ‘security’
is content free. Its all
someone elses problem.
• It’s not – every system needs
to understand its security
posture.
• Where do you check access
control?
• Where and do you store
credentials?
• Will you default to a safe
mode or an ‘all access pass
mode’ ?
• BTW - How much code gets
run before you say no?
Security Features
@spoole167
This is straightforward
If your system is too complex
to understand
Or just poorly written. It’s
more likely to have edge cases,
weak spots etc
So more open to being
attacked
Code Quality
#9 Keep it simple
# 10 Have a full test suite
# 11 test for failing conditions:
even security related
Poor code quality leading to unpredictable behaviour and
opportunities to stress the system in unexpected ways
@spoole167
Write code defensively
https://blog.jetbrains.com/idea/2017/09/code-smells-too-many-problems/
Often the path through the
code is decided only by the
data provided
Bad guys look for
unexpected paths by fuzzing
your data
Don’t have unexpected
states or code paths..
@spoole167
Encapsulation
Insufficient encapsulation of critical data or functionality
Errors that allow functionality or data
to cross trust boundaries
Escalation of data access privileges
Insecure import of untrusted code
Exposure of information through
unprotected resources
#12 use immutable state where at all possible
#13 Do not give away extraneous data
#14 Only hold the least amount of critical data – and throw it away as soon as possible
#15 Reduce functionality to just the usecases needed - No nice-to-haves !
@spoole167
#16 control of state never
leaves your system
• Client can send you requests
to change state but it must
never own the state.
Time and State
Unexpected interactions between threads, processes, time,
and information (shared state)
people put state into a cookie and
assume it cant be modified if
encrypted..
What happens if someone sends you
an encrypted state object from another
session…
Did you have a flag in the state that
said the user had higher privileges.?
@spoole167
• All the parts of your development
process
• The tools you use
• Your dependencies
• The operating system
• The build machines.
• The code repository
• All these can be vulnerable to
attack.
Environment
@spoole167
Authentication, access control, confidentiality,
cryptography, privilege management.
Unexpected interactions between
threads, processes, time, and information
(shared state)
Errors related to error handling
Problems caused by metacharacters,
alternate encodings and numeric
representations. General security problems
result from trusting input.
Using an API in a manner contrary to its
intended use
Insufficient encapsulation of critical data or
functionality
Everything that is outside of the source
code but is still critical to the security of the
application
Time and State
Poor code quality leading to unpredictable
behaviour and opportunities to stress the
system in unexpected ways.
Errors
API abuse
Code Quality
Security Features
Encapsulation
Input Validation and Representation
Environment
@spoole167
Summary
1. Hackers use sophisticated tooling to attack you
2. These tools look for known vulnerabilities and common design errors.
3. Everyone makes mistakes (some of which we don’t know about yet)
4. Relying on one single form of defense is the ultimate foolishness
5. Right now its about defense In depth
6. Make sure you have alarm systems: Invest in detection, invest in the
strongest encryption, invest in security testing, design for defense
7. Take a long hard look at your design choices – easy for developers = easy
for hackers
8. Turn your suspicion detector way up when using other peoples code
There are bad guys out there and your
application is at risk
Don’t make it worse by ignoring the problem
https://www.flickr.com/photos/koolmann/
@spoole167

More Related Content

PDF
jbang: Unleash the power of Java for shell scripting
PDF
What's new with Apache Camel 3? | DevNation Tech Talk
PDF
Building kubectl plugins with Quarkus | DevNation Tech Talk
PPTX
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
PDF
Spring Boot to Quarkus: A real app migration experience | DevNation Tech Talk
PDF
Writing Rust Command Line Applications
PDF
Terraform 101: What's infrastructure as code?
PDF
Pipeline+over view
jbang: Unleash the power of Java for shell scripting
What's new with Apache Camel 3? | DevNation Tech Talk
Building kubectl plugins with Quarkus | DevNation Tech Talk
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
Spring Boot to Quarkus: A real app migration experience | DevNation Tech Talk
Writing Rust Command Line Applications
Terraform 101: What's infrastructure as code?
Pipeline+over view

What's hot (20)

PPTX
Docker for PHP Developers - ZendCon 2016
PDF
Kubelet with no Kubernetes Masters | DevNation Tech Talk
ODP
An OpenShift Primer for Developers to get your Code into the Cloud (PTJUG)
PDF
Working with Xcode and Swift Package Manager
PDF
Jenkins & IaC
PPTX
Zend con 2016 bdd with behat for beginners
PDF
Building A SaaS with CoreOS, Docker, and Etcd
PDF
Import golang; struct microservice - Codemotion Rome 2015
PDF
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
PDF
DockerCon SF 2015: Enabling Microservices @Orbitz
PDF
OpenStack Preso: DevOps on Hybrid Infrastructure
PPTX
DockerCon EU 2015: Stop Being Lazy and Test Your Software!
PDF
Developing and Deploying PHP with Docker
PDF
Import golang; struct microservice
PDF
Monitoring Akka with Kamon 1.0
PPTX
TIAD 2016 : Migrating 100% of your production services to containers
PDF
DockerCon EU 2015: Trading Bitcoin with Docker
PPTX
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
PDF
Vagrant - the essence of DevOps in a tool
ODP
devops@cineca
Docker for PHP Developers - ZendCon 2016
Kubelet with no Kubernetes Masters | DevNation Tech Talk
An OpenShift Primer for Developers to get your Code into the Cloud (PTJUG)
Working with Xcode and Swift Package Manager
Jenkins & IaC
Zend con 2016 bdd with behat for beginners
Building A SaaS with CoreOS, Docker, and Etcd
Import golang; struct microservice - Codemotion Rome 2015
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
DockerCon SF 2015: Enabling Microservices @Orbitz
OpenStack Preso: DevOps on Hybrid Infrastructure
DockerCon EU 2015: Stop Being Lazy and Test Your Software!
Developing and Deploying PHP with Docker
Import golang; struct microservice
Monitoring Akka with Kamon 1.0
TIAD 2016 : Migrating 100% of your production services to containers
DockerCon EU 2015: Trading Bitcoin with Docker
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Vagrant - the essence of DevOps in a tool
devops@cineca
Ad

Similar to Seven perilous pitfalls to avoid with Java | DevNation Tech Talk (20)

PDF
Porting your favourite cmdline tool to Android
PDF
Dependent things dependency management for apple sw - slideshare
PPTX
The Anatomy of Java Vulnerabilities
ODP
RichFaces - Testing on Mobile Devices
KEY
Future of PHP
PPTX
Locking the Doors -7 Pernicious Pitfalls to avoid with Java
ODP
Who pulls the strings?
PDF
Having Fun with Play
PDF
Writing usableap isinpractice
PDF
Best Practices in apps development with Titanium Appcelerator
PDF
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
PDF
Release with confidence
PDF
Play framework
PDF
Is your python application secure? - PyCon Canada - 2015-11-07
PDF
You're Off the Hook: Blinding Security Software
PDF
Cocoapods and Most common used library in Swift
KEY
node.js: Javascript's in your backend
PPTX
PHP from soup to nuts Course Deck
PPTX
Anatomy of Java Vulnerabilities - NLJug 2018
KEY
Development workflow
Porting your favourite cmdline tool to Android
Dependent things dependency management for apple sw - slideshare
The Anatomy of Java Vulnerabilities
RichFaces - Testing on Mobile Devices
Future of PHP
Locking the Doors -7 Pernicious Pitfalls to avoid with Java
Who pulls the strings?
Having Fun with Play
Writing usableap isinpractice
Best Practices in apps development with Titanium Appcelerator
BEST PRACTICES PER LA SCRITTURA DI APPLICAZIONI TITANIUM APPCELERATOR - Aless...
Release with confidence
Play framework
Is your python application secure? - PyCon Canada - 2015-11-07
You're Off the Hook: Blinding Security Software
Cocoapods and Most common used library in Swift
node.js: Javascript's in your backend
PHP from soup to nuts Course Deck
Anatomy of Java Vulnerabilities - NLJug 2018
Development workflow
Ad

More from Red Hat Developers (20)

PDF
DevNation Tech Talk: Getting GitOps
PDF
Exploring the power of OpenTelemetry on Kubernetes
PDF
GitHub Makeover | DevNation Tech Talk
PDF
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
PDF
Extra micrometer practices with Quarkus | DevNation Tech Talk
PDF
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
PDF
Integrating Loom in Quarkus | DevNation Tech Talk
PDF
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
PDF
Containers without docker | DevNation Tech Talk
PDF
Distributed deployment of microservices across multiple OpenShift clusters | ...
PDF
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
PDF
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
PDF
11 CLI tools every developer should know | DevNation Tech Talk
PDF
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
PDF
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
PDF
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
PDF
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
PDF
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
PDF
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
PDF
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
DevNation Tech Talk: Getting GitOps
Exploring the power of OpenTelemetry on Kubernetes
GitHub Makeover | DevNation Tech Talk
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
Extra micrometer practices with Quarkus | DevNation Tech Talk
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
Integrating Loom in Quarkus | DevNation Tech Talk
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
Containers without docker | DevNation Tech Talk
Distributed deployment of microservices across multiple OpenShift clusters | ...
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
11 CLI tools every developer should know | DevNation Tech Talk
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk

Recently uploaded (20)

PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Empathic Computing: Creating Shared Understanding
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
Spectral efficient network and resource selection model in 5G networks
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
cuic standard and advanced reporting.pdf
PDF
Encapsulation theory and applications.pdf
PDF
KodekX | Application Modernization Development
Per capita expenditure prediction using model stacking based on satellite ima...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Programs and apps: productivity, graphics, security and other tools
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Empathic Computing: Creating Shared Understanding
Mobile App Security Testing_ A Comprehensive Guide.pdf
Big Data Technologies - Introduction.pptx
Spectral efficient network and resource selection model in 5G networks
The AUB Centre for AI in Media Proposal.docx
Diabetes mellitus diagnosis method based random forest with bat algorithm
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Encapsulation_ Review paper, used for researhc scholars
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
NewMind AI Weekly Chronicles - August'25 Week I
The Rise and Fall of 3GPP – Time for a Sabbatical?
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
cuic standard and advanced reporting.pdf
Encapsulation theory and applications.pdf
KodekX | Application Modernization Development

Seven perilous pitfalls to avoid with Java | DevNation Tech Talk

  • 2. @spoole167 This Session is about Java security • It’s about how to start thinking about secure application design • It’s about how to improve your development processes • It’s about why this really matters • It’s a taster only There’s not much Java in it..
  • 3. @spoole167 Software design flaws are grouped into “7 Pernicious Kingdoms”
  • 4. @spoole167 A bit of a marketing exercise • 2005 Fortify Software released a paper called “Seven Pernicious Kingdoms: A Taxonomy of Software Security Errors” • It caught on among the security community
  • 5. @spoole167 In fact there are more than 7 ☺
  • 6. @spoole167 Seven Pernicious Kingdoms Security Features Time and State Errors Input Validation and Representation API Abuse Code Quality Encapsulation Environment
  • 7. @spoole167 Seven Perilous Pitfalls For Java Security Features Time and State Errors Input Validation and Representation API Abuse Code Quality Encapsulation Environment
  • 8. @spoole167 Agenda Using real scenarios and other examples dip into the 7PK looking at code and thinking about design
  • 10. @spoole167 All You need is a firewall
  • 12. @spoole167 Internet network cluster Server Container……………………application Reality Bad guys are looking for exploits everywhere Vulnerabilities in the application Vulnerabilities in the container Vulnerabilities in the server Vulnerabilities in the cluster Vulnerabilities in the network
  • 14. @spoole167 First scenario • I’m developing a performance tool for Adopt OpenJDK • It’s designed to run locally but will eventually be hostable
  • 17. @spoole167 Problems caused by metacharacters, alternate encodings and numeric representations. General security problems result from trusting input. Input Validation and Representation
  • 18. @spoole167 Input Validation and Representation Forms Input. 1. Browser javascript code validates the form 2. Send the data to the server over a websocket as JSON. 3. Server turns JSON into Java Browser Server WS http
  • 19. @spoole167 Input Validation and Representation My application only expects local war files to be loaded… ‘file://dir/app.war’
  • 20. @spoole167 Input Validation and Representation My application only expects local war files to be loaded… ‘http://badserver.com/badapp.war’ What happens if I get this?
  • 21. @spoole167 Input Validation and Representation Pretty obviously you cannot ever trust what a client sends you. Ever. Browser Server
  • 22. @spoole167 Input from an end point is an obvious place to be cautious Think of it like this… Every API you write OR call. Whether REST interface or a simple class. Is a ‘contract’ If that contract is not explicit and enforced your code is vulnerable. Input Validation and Representation “It is the callers responsibility”
  • 23. @spoole167 Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Input Validation and Representation Adopt Server http My tool uses the docker command line interface to retrieve information and run containers “docker images” “docker run –it ubuntu /bin/bash”
  • 24. @spoole167 Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); } Path to the docker exe Where to put the output
  • 25. @spoole167 Input Validation and Representation Driver driver = new Driver(); … List l = driver.run(“ps –a”); if (driver.hasError() == false) { System.out.println(l); } public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 26. @spoole167 Input Validation and Representation Driver driver = new Driver(); … List l = driver.run(“ps –a”); if (driver.hasError() == false) { System.out.println(l); } public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 27. @spoole167 What’s wrong with this code? Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 28. @spoole167 This field is never validated. Does it really point to a docker executable? What would happen if it was set to some other executable? Could simply run a version check on it! “docker –version” Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 29. @spoole167 Even if the field was validated during construction it can still be changed afterwards. Relying on constructor validation only is also poor practise. (Re)validate before usage Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 30. @spoole167 What about this field? Set to “/tmp/docker.out” ? Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 31. @spoole167 What validation does Java.io.File do? Input Validation and Representation public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); }
  • 32. @spoole167 public File(String pathname) { if (pathname == null) { throw new NullPointerException(); } this.path = fs.normalize(pathname); this.prefixLength = fs.prefixLength(this.path); } private static final FileSystem fs = DefaultFileSystem.getFileSystem(); “A normal Win32 pathname contains no duplicate slashes, except possibly for a UNC prefix, and does not end with a slash. It may be the empty string. Normalized Win32 pathnames have the convenient property that the length of the prefix almost uniquely identifies the type of the path and whether it is absolute or relative” What validation does Java.io.File do? - Not much!
  • 33. @spoole167 File f=new File("../../../../../../../../../../../../../../../../etc/passwd"); System.out.println(f); Path p=f.toPath(); System.out.println(p); Path q=p.toRealPath(LinkOption.NOFOLLOW_LINKS); System.out.println(q); ../../../../../../../../../../../../../../../../etc/passwd ../../../../../../../../../../../../../../../../etc/passwd /etc/passwd Code Output Takeaway Validation is always your problem Input Validation and Representation
  • 34. @spoole167 Input Validation and Representation Who uses Java serialization?
  • 35. @spoole167 Input Validation and Representation Who uses Java serialization? Do you use RMI, JMX, JMS, Spring Service Invokers?
  • 36. @spoole167 XMLEncoder (XML) XStream (XML/JSON/various) Kryo (binary) Hessian/Burlap (binary/XML) Castor (XML) json-io (JSON) Jackson (JSON) Fastjson (JSON) Red5 IO AMF (AMF) Apache Flex BlazeDS (AMF) Flamingo AMF (AMF) GraniteDS (AMF) WebORB for Java (AMF) SnakeYAML (YAML) jYAML (YAML) YamlBeans (YAML) Input Validation and Representation How about one of these?
  • 37. @spoole167 Input Validation and Representation Any place you rely on: persistence, messaging, remote ejb rmi / jmx , rmi-iiop, CDI There’s some form of serialization going on.
  • 38. @spoole167 public class LayerCake { private int layers; public LayerCake(int layers) { if(layers<1 || layers > 3) throw new IllegalArgumentException("number of layers is invalid"); this.layers=layers; } Constructors do not get called During deserialisation So I can make this value anything I want What the bad guys do
  • 39. @spoole167 Input Validation and Representation https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet What the good and bad guys do
  • 40. What the bad guys do
  • 41. What the bad guys do
  • 42. @spoole167 With serialisation vulnerabilities I may be able to get the code to overwrite a critical file somewhere else. If I modify both the exe and file fields I can control what data gets written to your system What the bad guys do public class Driver { private static final String DEFAULT_EXEC = "/usr/local/bin/docker"; private boolean error; private String docker; private File outputFile; private List results=new LinkedList(); public Driver() { this(DEFAULT_EXEC); } public Driver(String driver) { docker = driver; outputFile = new File("/tmp/docker.out"); } Remember, constructors are not called during deserialization. The data is simply inserted.
  • 43. @spoole167 Protecting yourself against serialization exploits is hard And remember – it’s not just your code. Its all your dependencies too! Another talk
  • 44. @spoole167 #1: all data received must be considered untrusted and potentially dangerous. • Data means anything that comes in – command lines, env variables, sockets, GUI, REST , even data coming from your own server… • You must never trust the systems who send you data. • You can almost never trust the systems you retrieve data from • You must validate data when you get it AND before you use it Input Validation and Representation
  • 45. @spoole167 Using an API in a manner contrary to its intended use API Abuse
  • 46. @spoole167 API Abuse My tool tags all the containers it creates with “adoptopenjdk=true” That makes it easier to retrieve only the relevant containers when talking to docker. I have a test to check I can create such containers String id = createSimpleContainer(TEST_IMAGE_NAME); ContainerInfo ci=inspectContainer(id); assertTrue(ci.labels().containsKey(“adoptopenjdk”);
  • 47. @spoole167 API Abuse But I want to make sure that the calls to docker are really working. So I have a ‘get all’ method. It’s not used in production But its exposed as a test end point… String id = createSimpleContainer(TEST_IMAGE_NAME); List<Container> allc = allContainerList(); assertTrue(allc.isEmpty()==false); get("/test/v1/*" , (req, res) ->plimsoll.test_v1_request.handleRequest(req,res));
  • 48. @spoole167 API Abuse A common vulnerability pattern is to find hidden end points like ones just for testing. Reading the code on github or just Googling for your sites metadata can easily reveal them And of course test end points tend to have less security  Never have APIs that are just for ‘testing’ or bypass normal authentication processes..
  • 49. @spoole167 Google search: intitle:index.of WEB-INF I found something… What the bad guys do
  • 51. @spoole167 API Abuse My tool allows for complex scenarios to be created. JVM = Hotspot or OpenJ9 App Server = Tomcat or Jetty Various versions strings. The combinations are sent one by one… JVM=Hotspot, AppServer=Tomcat, AppVersion=9.0
  • 52. @spoole167 API Abuse The code validates the entries as being individually correct.. ✓ JVM=Hotspot ✓ AppServer=Tomcat ✓ AppVersion=9.4.9 But not that the combinations are valid!
  • 53. @spoole167 API Abuse My code also returns lists of containers so there are page / page size type parameters.. “list containers from page 7 with page size 100” “list containers from page 1 with page size 10”
  • 54. @spoole167 API Abuse My code also returns lists of containers so there are page / page size type parameters.. “list containers from page 7 with page size 100” “list containers from page 1 with page size 10” What about.. “list containers from page 0 with page size -100” “list containers from page -1 with page size 10” “list containers from page MAX_INT with page size -MAX_INT”
  • 55. 55 Try likely entry points and all the http verbs GET /users/1 DELETE /api/v1/users/1 OPTIONS /api/v1/user/1 HEAD /api/v1/user/1 POST /users/1 What the bad guys do
  • 56. 56 Play with the headers and cookies POST /api/v1/user HTTP/1.1 Host: developer.mozilla.org Content-Length: 64 Content-Type: application/x- www-form-urlencoded What the bad guys do
  • 57. 57 Can I get the service to fail or break? 404 “Not Found” 503 “Service Unavailable” “500 Internal Server Error” Different errors from different components? What the bad guys do
  • 58. 58 If I can find a static endpoint service I might be able to get at the filesystem… GET /api/v1/images/a/../../../../../../etc/passwd What the bad guys do
  • 59. 59 Fuzzing calls and data.. GET /users/1 POST /users/2 PUT /users/20000?name=“(select GET /users/-1 GET /users/$INT_MAX What the bad guys do
  • 60. 60 What the bad guys do
  • 61. 61 Fuzzing calls and data. Fuzz urls, json payloads, xml payloads, binary payloads … Import / export / upload / download options .. Command line options, file formats … “known-to-be-dangerous” values In the public domain Widespread & mature Automatic ‘protocol’ detection & exploitation What the bad guys do
  • 62. @spoole167 #2 Never give control to the caller by accepting unconstrained instructions • Calling endpoints that are hidden • Finding hidden fields in your requests and changing them • Sending unexpected but pseudo-valid combinations of data • Exploring the data ranges (+ and - ) • Using an API out of context. (like credit card validation) • Exploiting query languages (SQL injection plus. JQ, or Xpath etc) • most systems assume any call to it is correct and do minimal validation once the individual elements are accepted. API Abuse
  • 64. @spoole167 Errors private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); File f = new File("plimsoll.properties"); if (f.exists()) { FileReader fr; try { fr = new FileReader(f); p.load(fr); fr.close(); } catch (IOException e) { } return p; } Some code – reads a config file…
  • 65. @spoole167 Errors private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); File f = new File("plimsoll.properties"); if (f.exists()) { FileReader fr; try { fr = new FileReader(f); p.load(fr); fr.close(); } catch (IOException e) { } return p; } Don’t assume that only the errors you expect will occur - such as FileNotFoundException
  • 66. @spoole167 Errors private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); File f = new File("plimsoll.properties"); if (f.exists()) { FileReader fr; try { fr = new FileReader(f); p.load(fr); fr.close(); } catch (FileNotFoundException e) { // allowed } catch (IOException e) { // not expected } return p; } Better!
  • 67. @spoole167 Errors Catching or throwing exceptions in a more generic manner than needed can hide the activities of the attacker Either because of a lack of specific info in logging and log analysis i.e: “Config file not found”. Vs “Unexpected IO Error reading the config file” Or simply because the unusual exception is treated as usual
  • 68. @spoole167 Errors Catching or throwing exceptions in a more generic manner than needed can hide the activities of the attacker Either because of a lack of specific info in logging and log analysis i.e: “Config file not found”. Vs “Unexpected IO Error reading the config file” Or simply because the unusual exception is treated as usual BTW - catching NullPointer Exceptions as a way of detecting ‘expected’ nulls is also poor practice – as described above. You simply can’t tell which NPE is which.
  • 70. @spoole167 <account> <name> Mega Corp Limited </name> <address> The Citadel London SW1 </address> <balance amount="100" currency="EURO"/> </account> You have some XML
  • 71. @spoole167 <account> <name> Mega Corp Limited </name> <address> The Citadel London SW1 </address> <balance amount="100" currency="EURO"/> </account> { name: "Mega Corp Limited", address : { line1: "The Citadel", city: "London", postcode: "SW1" }, balance: { amount: 100, currency: "EURO" } } Which you have to convert to JSON
  • 72. @spoole167 JsonObject jo=new JsonObject(); for(int i=0;i<l.getLength();i++) { Node n= l.item(i); switch( n.getNodeName() ) { case "address" : jo.add(parseAddress(n)); break; case "name" : jo.add(parseName(n)); break; case "balance" : jo.add(parseBalance(n)); break; } } You write some code
  • 73. @spoole167 <account> <name> Mega Corp Limited </name> <address> The Citadel London SW1 </address> <balance amount="100" currency="EURO"/> <overdraft limit=”500" /> </account> And then the XML changes
  • 74. @spoole167 JsonObject jo=new JsonObject(); for(int i=0;i<l.getLength();i++) { Node n= l.item(i); switch( n.getNodeName() ) { case "address" : jo.add(parseAddress(n)); break; case "name" : jo.add(parseName(n)); break; case "balance" : jo.add(parseBalance(n)); break; case ”overdraft": jo.add(parseOverdraft(n)); break; } } So you have to change your code
  • 75. @spoole167 This happens a lot<account> <name> Mega Corp Limited </name> <address> The Citadel London SW1 </address> <balance amount="100" currency="EURO"/> <overdraft limit=”500" /> <credit>Low</credit> </account>
  • 76. @spoole167 String handlerName = handlers.getProperty(n.getNodeName().toLowerCase()); try { Class c = Class.forName(handlerName); IHandler handler = (IHandler) c.newInstance(); jo.add(handler.convert(handler)); } catch (Exception e) { String errorInfo = "could not create class for handler" + n.getNodeName() + " class=" + handlerName; throw new IOException(errorInfo, e); } } private static Properties handlers = new Properties(file,System.getProperties()); You change your code address=com.foo.standard.AddressHandler balance=com.foo.standard.BalanceHandler name=com.foo.standard.NameHandler
  • 78. @spoole167 And when things go wrong you get a nice error message java.io.IOException: could not create class for handler credit class=null String errorInfo = "could not create class for handler" + n.getNodeName() + "class=" + handlerName; throw new IOException(errorInfo, e); Missing handler in the properties file
  • 79. @spoole167 And when things go wrong you get a nice error message java.io.IOException: could not create class for handler credit class=com.foo.handler.CreditHandler String errorInfo = "could not create class for handler" + n.getNodeName() + "class=" + handlerName; throw new IOException(errorInfo, e); Missing class on the classpath
  • 80. @spoole167 What happens with this data? <account> <name> Mega Corp Limited </name> <address> The Citadel London SW1 </address> <balance amount="100" currency="EURO"/> <java.ext.dirs/> </account> What the bad guys do
  • 81. @spoole167 String errorInfo = "could not create class for handler" + n.getNodeName() + "class=" + handlerName; throw new IOException(errorInfo, e); java.io.IOException: could not create class for handler java.ext.dirs class =/Users/spoole/Library/Java/Extensions: /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/ext: /Library/Java/Extensions:/Network/Library/Java/Extensions: /System/Library/Java/Extensions: /usr/lib/java What the bad guys do
  • 82. 82 Stack traces and error messages really help More help I’m on the right track More component info What the bad guys do
  • 83. @spoole167 Google search: intitle:Error Page pageWrapper.jsp? I found something… What the bad guys do
  • 84. @spoole167 java.lang.NullPointerException at com.stoneware.server.auth.OpenIDProviders.getProviderFromUrl(qx:91) at org.apache.jsp.openid.openIDClaim_jsp._jspService(openIDClaim_jsp.java:248) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) at org.eclipse.jetty.jsp.JettyJspServlet.service(JettyJspServlet.java:107) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) at com.stoneware.filter.VersionCheckFilter.doFilter(wtb:391) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.filter.SecurityFilter.doFilter(sed:802) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.relay.b.A.doFilter(tlc:1671) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.filter.SessionIDFilter.doFilter(bvb:1475) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at com.stoneware.relay.managers.f.doFilter(or:500) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:542) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:332) at org.eclipse.jetty.servlets.gzip.GzipHandler.handle(GzipHandler.java:479) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:190) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:499) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Unknown Source) Error traces can be used to identify what you’re running – down to working out the version number… What the bad guys do
  • 85. 85 Log / alert unexpected behavior ✓ Build in an expectation of what the client will be doing with the data. ✓ All log entries must be useful – generic errors don’t help. ✓ Be careful about the amount of extra info in a log – remember the bad guys may gain access to them too Following good API design doesn’t mean you have to be too helpful. Errors
  • 86. @spoole167 #3 Error paths are as critical as normal flows #4 Report only enough information to identify the situation • In general we’re poor at dealing with errors in our code. • Developers focus on the positive side. • With consequential lack of testing for error paths and checking correct behavior Errors
  • 87. @spoole167 Security Features Authentication, access control, confidentiality, cryptography, privilege management.
  • 88. @spoole167 Can you rely on having a secure encrypted connection? Browser Exploit Against SSL/TLS (BEAST) Compression Ratio Info-leak Made Easy (CRIME) Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext (BREACH) Padding Oracle On Downgraded Legacy Encryption (POODLE) What the bad guys do
  • 89. @spoole167 All data to and from the API is public Even if you have a secure connection to the client Man in the middle Reverse engineered client or app Malware / xss In the browser What the bad guys do
  • 90. 90 Read the logs What the bad guys do
  • 91. @spoole167 Phew. • So many things ways your application can be vulnerable. • Security is not something you add after. It’s always a part of your design thinking.
  • 92. @spoole167 Security Features “I don’t need any security as the system is local…” “I’ll add security later” “I’m not sure what security means”
  • 93. @spoole167 Security Features Many vulnerabilities come from poor authentication and access control methods but ‘Security’ is a wider topic. Confidentiality : Managing the data in your care Cryptography : methods to ensure information is kept private Privilege management: Ensuring actors are who they say they are
  • 94. @spoole167 “I don’t need any security as the system is local…” Security Features Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Adopt Server http
  • 95. @spoole167 “I don’t need any security as the system is local…” Security Features Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Adopt Server http The browser is vulnerable to Cross Site Scripting attacks. So a remote attacker could get on to your system
  • 96. @spoole167 “I don’t need any security as the system is local…” Security Features Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Adopt Server http Since my tool uses an API that is unconstrained (ie the command line). The attacker could do anything And the tool is downloading and running code from the web – another attack point
  • 97. @spoole167 “I don’t need any security as the system is local…” Security Features Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Adopt Server http The docker instance may have access to a secure repository. Without security my tool is enabling an easy bypass of any access controls. The contents of the server are now available for a hacker to explore or use.
  • 98. @spoole167 “I don’t need any security as the system is local…” Security Features Browser Server Docker Daemon Remote repositories Local repositories WS Cmd line http Adopt Server http So actually my tool needs really good security features.
  • 99. @spoole167 Security Features A few examples of vulnerable designs
  • 100. @spoole167 Security Features Trusting the end user not to tamper with the data Cookie[] cookies = request.getCookies(); for (int i =0; i< cookies.length; i++) { Cookie c = cookies[i]; if (c.getName().equals("role")) { userRole = c.getValue(); } }
  • 101. @spoole167 Security Features Trusting the end user not to tamper with the data Cookie[] cookies = request.getCookies(); for (int i =0; i< cookies.length; i++) { Cookie c = cookies[i]; if (c.getName().equals("role")) { userRole = c.getValue(); } } Does encryption solve this?
  • 102. @spoole167 Security Features Trusting the end user not to tamper with the data Cookie[] cookies = request.getCookies(); for (int i =0; i< cookies.length; i++) { Cookie c = cookies[i]; if (c.getName().equals("role")) { userRole = c.getValue(); } } No! XSS attacks often replace encrypted cookies etc with ones from another session that has the required privileges. You must have additional privilege management processes in play
  • 103. @spoole167 Security Features Having endpoints that allows the client to read the config get: ”/api/v1/config/<key_name>”. Returns json : { “key”: key_name , “value” : value } public String getConfigValue(String key) { return config.getProperty(key); } private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); .. Poor confidentiality management
  • 104. @spoole167 Security Features My code has a endpoint that allows the client to read the config get: ”/api/v1/config/<key_name>”. Returns json : { “key”: key_name , “value” : value } public String getConfigValue(String key) { return config.getProperty(key); } private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); .. Poor confidentiality management Since the config was backed by System.getProperties all system properties are exposed..
  • 105. @spoole167 Google search: intitle:index.of WEB-INF I found something… What the bad guys do
  • 108. @spoole167 Another Google search: inurl:”8080/jmx-console” This dork will list all unauthenticated jboss servers with jmx-console access. I found something… What the bad guys do
  • 109. @spoole167 private Properties loadConfig() { Properties p = new Properties( System.getProperties() ); File f = new File("plimsoll.properties"); if (f.exists()) { FileReader fr; try { fr = new FileReader(f); p.load(fr); fr.close(); } catch (IOException e) { } return p; } Security Features Unsophisticated credentials management -Ddocker.user=foo -Ddocker.password=bar. Storing information In text files. Easily readable. Easily changed on the command line. (turns up in the logs)
  • 110. @spoole167 Yet another Google search: filetype:password jmxremote I found something… # # Following are two commented-out entries. The "measureRole" role has # password "QED". The "controlRole" role has password "R&D". # monitorRole C0gnitive! controlRole C0gnitive! What the bad guys do
  • 111. @spoole167 Security Features Unsophisticated credentials management That end up in your git repo… Q: Can you easily remove password data from your repo once committed?
  • 112. @spoole167 Security Features Unsophisticated credentials management That end up in your git repo… A: these people seem to think so..
  • 113. @spoole167 TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( X509Certificate[] certs, String authType) { } public void checkServerTrusted( X509Certificate[] certs, String authType) { } public boolean isClientTrusted( X509Certificate[] cert) { return true; } public boolean isServerTrusted( X509Certificate[] cert) { return true; } }} Security Features Deliberate weakening of security protocols
  • 114. @spoole167 Github search “implements TrustManager” I found something… What the bad guys do
  • 115. @spoole167We’ve found 72,609 code results AlwaysValidTrustManager TrustAllServersWrappingTrustManager A very friendly, accepting trust manager factory. Allows anything through. all kind of certificates are accepted and trusted. A very trusting trust manager that accepts anything // Install the all-trusting trust manager OverTrustingTrustProvider AllTrustingSecurityManagerPlugin.java AcceptingTrustManagerFactory.java AllTrustingCertHttpRequester.java Security Features
  • 116. @spoole167We’ve found 72,609 code results AlwaysValidTrustManager TrustAllServersWrappingTrustManager A very friendly, accepting trust manager factory. Allows anything through. all kind of certificates are accepted and trusted. A very trusting trust manager that accepts anything // Install the all-trusting trust manager OverTrustingTrustProvider AllTrustingSecurityManagerPlugin.java AcceptingTrustManagerFactory.java AllTrustingCertHttpRequester.java Security Features How many are in your dependencies?
  • 117. @spoole167 Security Features Defaulting to full access or running too much under privilege method() { AccessController.doPrivileged( new PrivilegedAction()) { public Object run() { // my app goes here } }; }
  • 118. @spoole167 #5 Access controls as near to business logic as possible #6 Keep credentials encrypted, safe and out of memory #7 Fail safely #8 Know your responsibilities for others • For many the word ‘security’ is content free. Its all someone elses problem. • It’s not – every system needs to understand its security posture. • Where do you check access control? • Where and do you store credentials? • Will you default to a safe mode or an ‘all access pass mode’ ? • BTW - How much code gets run before you say no? Security Features
  • 119. @spoole167 This is straightforward If your system is too complex to understand Or just poorly written. It’s more likely to have edge cases, weak spots etc So more open to being attacked Code Quality #9 Keep it simple # 10 Have a full test suite # 11 test for failing conditions: even security related Poor code quality leading to unpredictable behaviour and opportunities to stress the system in unexpected ways
  • 120. @spoole167 Write code defensively https://blog.jetbrains.com/idea/2017/09/code-smells-too-many-problems/ Often the path through the code is decided only by the data provided Bad guys look for unexpected paths by fuzzing your data Don’t have unexpected states or code paths..
  • 121. @spoole167 Encapsulation Insufficient encapsulation of critical data or functionality Errors that allow functionality or data to cross trust boundaries Escalation of data access privileges Insecure import of untrusted code Exposure of information through unprotected resources #12 use immutable state where at all possible #13 Do not give away extraneous data #14 Only hold the least amount of critical data – and throw it away as soon as possible #15 Reduce functionality to just the usecases needed - No nice-to-haves !
  • 122. @spoole167 #16 control of state never leaves your system • Client can send you requests to change state but it must never own the state. Time and State Unexpected interactions between threads, processes, time, and information (shared state) people put state into a cookie and assume it cant be modified if encrypted.. What happens if someone sends you an encrypted state object from another session… Did you have a flag in the state that said the user had higher privileges.?
  • 123. @spoole167 • All the parts of your development process • The tools you use • Your dependencies • The operating system • The build machines. • The code repository • All these can be vulnerable to attack. Environment
  • 124. @spoole167 Authentication, access control, confidentiality, cryptography, privilege management. Unexpected interactions between threads, processes, time, and information (shared state) Errors related to error handling Problems caused by metacharacters, alternate encodings and numeric representations. General security problems result from trusting input. Using an API in a manner contrary to its intended use Insufficient encapsulation of critical data or functionality Everything that is outside of the source code but is still critical to the security of the application Time and State Poor code quality leading to unpredictable behaviour and opportunities to stress the system in unexpected ways. Errors API abuse Code Quality Security Features Encapsulation Input Validation and Representation Environment
  • 125. @spoole167 Summary 1. Hackers use sophisticated tooling to attack you 2. These tools look for known vulnerabilities and common design errors. 3. Everyone makes mistakes (some of which we don’t know about yet) 4. Relying on one single form of defense is the ultimate foolishness 5. Right now its about defense In depth 6. Make sure you have alarm systems: Invest in detection, invest in the strongest encryption, invest in security testing, design for defense 7. Take a long hard look at your design choices – easy for developers = easy for hackers 8. Turn your suspicion detector way up when using other peoples code
  • 126. There are bad guys out there and your application is at risk Don’t make it worse by ignoring the problem https://www.flickr.com/photos/koolmann/ @spoole167