Secure coding practices in Java: challenges and vulnerabilities Meng et al., ICSE’18

TL;DR : don’t trust everything you read on Stack Overflow.

Meng et al. conduct a study of Stack Overflow posts relating to secure coding practices in Java to find out the hot topics, what people struggle with, and whether or not the accepted answers are actually following security best practices.

We conducted an empirical study on Stack Overflow posts, aiming to understand developer’s concerns on Java secure coding, their programming obstacles, and insecure coding practices. We observed a wide adoption of the authentication and authorization features provided by Spring Security — a third-party framework designed to secure enterprise applications…

Well, how could I resist reading that! (Some readers may know that I was for many years the CTO of SpringSource). Spring Security does come in for some flak in this paper for the high volume of questions that are asked relating to it. There’s no calibration though for underlying popularity. One of the reasons there are a lot of questions, I posit, is that there are an awful lot of users of Spring Security. Spring Boot applications will use Spring Security, and Spring Boot has been growing at an amazing rate these last few years (many millions of downloads every month, and still ticking along at over 300% y-o-y growth). Another reason is that Spring Security has been around a long time, and the survey covers questions going back to 2008, when Spring Security used an older XML-based configuration style. Spring Security genuinely was hard to configure in the early days. In fact, the origins of Spring Security were in a project called “Acegi” created by the wonderful Ben Alex. Ben Alex himself introduced a phrase that became part of the SpringSource folklore when talking about a project to simplify Acegi configuration “whenever someone uses Acegi, a fairy dies.” That was all a long time ago, and the modern Spring Security is a very different beast.

The authors crawl 22,195 Stack Overflow posts containing the keywords ‘Java’ and ‘security,’ then filtered out those without accepted answers or with negative votes, and those without code snippets. After manually inspecting the remaining posts for relevance, the result is a set of 503 posts with dates from 2008 to 2016. The posts are then analysed to determine the most common security concerns, programming challenges, and vulnerabilities.

What are people asking about?

Most questions are to do with how to get something to work (implementation questions), rather than questions seeking to understand security design. The ‘how do I…’ questions were further broken down based on the platform being discussed: Java platform security, Java EE security, or Spring Security. Spring Security gets the most questions (56%)!

Seven major security topics emerge from a second-level classification of the implementation posts:

Java platform: cryptography, access control, & secure communication

Java EE security

Spring Security: authentication, authorisation, and configuration

We can see the volume of questions in these topic areas growing and the distribution changing over time.

During 2009-2011, most posts were about Java platform security. However, since 2012, the major security concern has shifted to securing enterprise Java applications (including both Java EE security and Spring Security). Specifically, Spring Security has taken up over 50% of the posts published every year since 2013.

Common challenges (over the 8 year period)

Taking the five most popular topic areas (authentication, cryptography, Java EE security, and secure communication), the authors did a further analysis to understand common challenges. The biggest topic area by far is authentication (more than all the others combined).

Recall that the authentication topic is specific to Spring Security. Here people want to know (i) how to integrate Spring Security with different application servers and frameworks, (ii) how to configure Spring Security using XML (84 q’s) or Java (42 q’s), and (iii) how to convert XML-based configurations to Java-based ones. The Spring family of projects originally all used exclusively XML-based configuration. But this has not been true for a long time. Today the preferred approach is Java based configuration, which has been supported in Spring Security since the 3.2.0 release in 2013. Even so,…

… there are lots of annotations and APIs of classes, methods, and fields available to specify different configuration options… implicit constraints and subtle requirements are not well documented.

(Here are the latest guides for the 5.0.6 release. If you’re starting from scratch, go the Spring Boot way).

Developers also struggle converting older XML-based projects to use Java configuration.

When it comes to cryptography (Java platform), users struggle with poor error messages, implicit constraints, and the difficulties involved in encrypting data using one programming language, and decrypting it in another.

The cryptography posts were mostly about key generation and usage. Developers asked these questions mainly due to clueless error messages, cross-language data handling, and implicit API usage constraints.

Access control posts mostly concerned how to restrict untrusted code from accessing certain packages, classes, and methods. There were also 9 posts on applets, which highlights some of limitations of a study that goes back to 2008. The only good answer to a question on applets in 2018 is “don’t use applets!”.

Security communication posts mainly discussed the process of establishing SSL/TLS connections. This process contains so many steps that developers were tempted to accept a broken solution to simply bypass the security verification.

Vulnerabilities

Does Stack Overflow give good advice? Sometimes, yes! But… “we identified security vulnerabilities in the accepted answers of three frequently discussed topics: Spring Security’s csrf() , SSL/TLS, and password hashing“. A common theme seems to be “my security policy is stopping me doing something,” answered by “disable security!”

Spring Security enables CSRF protection by default, and the corresponding token needs to be included in PATCH, POST, PUT and DELETE methods. Fail to do that, and things won’t work as expected. Or you could just disable CSRF protection! (Don’t).

In one instance, after accepting the vulnerable solution, an asker commented “Adding csfr().disable() solved the issue!!! I have no idea why it was enabled by default.”

In the SSL/TSL topic area certification verification is a pain. That doesn’t mean you don’t need to do it though! 9 out of 10 posts in this area had an accepted answer with an insecure solution bypassing security checks by trusting all certificates and/or allowing all hostnames. The implications are not always well understood.

Disabling the SSL certificate validation process completely destroys the secure communication protocol, leaving clients susceptible to man-in-the-middle (MITM) attacks… A developer justified the verification-bypassing choice by stating “I want my client to accept any certification (because I’m only ever pointing to one server).”

When it comes to password hashing, there’s also a bunch of outdated and wrong advice around.

3 out of 6 hashing-relevant posts accepted vulnerable solutions as correct answers, indicating that developers were unaware of best secure programming practices. Incorrect security information may propagate among Stack Overflow users and negatively influence software development.

Recommendations

The authors have the following common sense recommendations to make as a result of their study:

Developers should conduct security testing to check whether features work as expected. Security checks should not be disabled – even as a ‘temporary’ fix in dev or test. Be careful following advice found on Stack Overflow as some solutions may be out of date or insecure.

Library designers should deprecate APIs not intended to be used anymore, improve error messages, and design simplified APIs with strong security defenses implemented by default.

Tool builders can help by creating automatic tools to diagnose security errors, locate buggy code, and suggest security patches or solutions.

You may not be surprised to hear that…