Keeping Your Java Applications Secure
Java security is an important topic for all businesses that use Java applications. Java Champion Simon Ritter takes a deep dive into the JDK and the potential shortcomings of not keeping your applications up to date, as well as why it’s essential to know the difference between critical patch updates (CPUs) and patch set updates (PSUs).
A little over a year ago, in April 2019, the way most Java users accessed updates for the JDK changed. The reason for this was a combination of changes made by Oracle to how the JDK is developed and the licensing terms of the Oracle JDK.
The Oracle JDK 11 and Oracle JDK 8 (from update 211) now use the Oracle Technology Network License Agreement. This limits free use to only four cases:
- Personal use (laptop or desktop for personal applications)
- Development use
- Oracle approved product use
- Oracle cloud infrastructure use
For all other cases, a Java SE subscription must be purchased from Oracle.
This has required users to make decisions about their JDK deployment strategy. One such approach is “well, it works fine on the JDK we have now; let’s just stick with that”.
There is an obvious flaw to this, which is the effect this decision will have on the security of applications.
Ever since people started developing software, other people have been trying to find ways to use it in ways not originally intended. This is often for malicious goals such as stealing credit card numbers or user’s identities. We use the term hacker to describe someone who is able to subvert computer security. There are a myriad of ways that hackers use to achieve their goals; from fooling people into revealing confidential information (phishing) to sophisticated manipulation of software through techniques like buffer overruns.
Unfortunately, the more complex a piece of software, the more likely there is to be a vulnerability that hackers can exploit. The JDK is a very complex piece of software and, as such, may contain vulnerabilities.
As vulnerabilities in software are discovered, they are normally recorded as a Common Vulnerability and Exposure (CVE). The National Cybersecurity FFRDC, operated by the Mitre Corporation, maintains the CVE database. Each CVE, identified by a unique number, has a textual description of the vulnerability.
Additionally, each CVE has a Common Vulnerability Scoring System (CVSS) value. This is not included in the CVE but maintained in the National Vulnerability Database hosted by the National Institute for Science and Technology (NIST). The CVSS provides a base score and a set of metrics. The base score is a value between 0.1 and 10.0 that indicates the severity of the vulnerability (technically, the base score starts at 0.0 but anything with a score of zero is, by definition, not a vulnerability). The base score is calculated from the set of metrics, which indicate different aspects of the vulnerability. The metrics relate to things such as whether the vulnerability can be exploited across a network, whether physical access to a machine is required, etc. The base scores are divided into bands to make it simpler to determine the overall risk associated with a vulnerability:
- 0.0: None
- 0.1-3.9: Low
- 4.0-6.9: Medium
- 7.0-8.9: High
- 9.0-10.0: Critical
Let’s look at how important it is to keep your JDK up to date.
To start with I went back through the last three years of updates and extracted the vulnerability with the highest CVSS base score that was addressed in each. This is shown in the table below.
|CPU Date||Highest CVSS||Impacted JDK Versions|
|July 2020April 2020
|January 2018||8.3 (multiple)||6,7,8,9|
|October 2017||9.6 (multiple)||6,7,8,9|
|July 2017||9.6 (multiple)||7,8|
As you can see, most updates address at least one high scoring vulnerability with several addressing critical ones. When we restrict this to just the updates since the change in Oracle Java SE licensing, we still see one with a critical vulnerability and three with high ones. As an interesting aside, the critical vulnerability addressed in the April 2019 update was in a Windows DLL used to build the JDK, not in any JDK code.
Next, I analysed all the updates since January 2015, which was all the readily available information. Looking at all vulnerabilities addressed and dividing them into the risk groupings, we can produce a bar chart, as shown below:
I separated the critical ones into two to highlight how many with a score of ten there were.
As you can see, there have been a total of 320 CVEs addressed, the majority of which are in the low to medium range. The number of critical CVEs is 59, which should make you think about the importance of keeping your JDK up to date.
There is a bit more of a complication, however.
Oracle provides two different versions of each update; this is the same for all of their software. These are called Critical Patch Updates (CPUs) and Patch Set Updates (PSUs).
The CPU contains only the changes that relate to addressing security vulnerabilities. The PSU provides all those changes, plus any other bug fixes, minor enhancements, etc. The reason for doing this is to enable a quick rollout of an update if critical vulnerabilities need to be patched. Since the CPU contains a smaller set of changes, it is less likely to have an impact on the stability of application (i.e. less likely to stop your application from working). Having done touch-testing with the CPU, you can deploy it to ensure maximum security for your applications. You can then spend longer testing the PSU (typically running a full set of regression tests) before deploying that to production machines. This ensures maximum stability for your applications.
An important note here is that not all OpenJDK binary providers understand the distinction between a CPU and PSU. Some call their update a CPU when, in fact, it is the PSU. You should look closely at what you are getting before deploying.
To highlight the benefit of having both a CPU and PSU, we only need to look at the July 2020 update. This included a fix for a bug that, in itself, introduced a regression. The impact of this regression was that heavily used software, like Hadoop Cluster, Solr and Lucene no longer worked reliably, which is a severe issue for mission-critical applications using them. The regression was not in a security patch and therefore not included in the CPU.
The regression was resolved by a fix to the fix, issued as update 265, on July 27th, which was twelve days after the release of the scheduled July update. The initial update contained a fix to a CVE with a base score of 8.3, details of which were made public in the release notes. Had you been using one of the affected software systems, Hackers would have had nearly two weeks to try to exploit this if you only had the all-inclusive PSU. If you also had access to the CPU, you could have rolled out the necessary security patches, secured your systems against the threat and waited, free from worry, for the revised PSU to be released.
Azul’s Zulu Enterprise builds of the OpenJDK are targeted at users who want to ensure their systems deliver both the maximum level of security and stability. In addition to providing both the CPU (security) and PSU (full) versions of each update, we endeavour to deliver those updates as quickly as possible after Oracle release their version. Since the end of free public updates to JDK 8, Zulu Enterprise customers have been able to download the update within one hour of the Oracle release. This is, essentially, simultaneously.
In conclusion, it should be evident how important it is to ensure that all your systems running JVM-based applications are maintained with the latest updates.
Are your Java runtimes as secure as they should be?