Over the last decade of cloud migration, the threat model against Java applications and the way that we need to defend them has shifted. OpenJDK has made one positive change in this area already by deprecating the old SecurityManager, a relic that protected a bygone era of AOL CDs and paper maps. The next positive change in security is to strengthen the supply chain of software components, know what’s running and what’s vulnerable, and communicate this information with non-technical experts whose data is at risk.
Part of this threat model is driven by vulnerable libraries like last year’s Log4j. Although Log4j is a great logging library and was active on patching, many teams scrambled to identify where they needed to apply those patches. For individual Java developers or teams that knew their code and could deploy, the patch was simple — you updated a library and that was it. The reality though is that software moves fast and far, often leaving the locus of control of these technical experts to stakeholders that don’t have the expertise to manage a problem at this level. In a scramble, teams that did not know Java-specifics looked everywhere including .NET software and Python forums. The government of Quebec shut services down until they knew where Log4j wasn’t. This scrambling was not effective and does not protect our data.
A major part of a Java application’s threat model now involves the ability to track components and understand where our applications contain known-vulnerable components such as Log4j.
What Is a Common Java Application’s Supply Chain?
A simple way to look at the supply chain is that most participants are producers and/or consumers. Enterprise architects may already be familiar with the analogy, as supply chains move like queues and thus can use similar terminology. Examples of this supply chain include:
- Repositories like Maven Central are producers of JAR files. They provide these components to developers or build systems, who are the consumers of these JAR files.
- Developers consume JAR files and produce new code that puts an application together. Some developers produce libraries that are sent back in to Maven Central, who is the consumer.
- Build environments consume the developer’s custom code and repo libraries to produce an application, container, or other bundle.
- When the application is deployed to an environment or sent to customers, this generally ends the supply chain.
- For purchased COTS software, the vendor is the producer and the operator is generally the consumer. Internally the vendor has their own supply chain of how they made the software.
The ultimate goal is to move applications to production and run them — this production environment is only a consumer because it does not produce new artifacts (in DevOps cycles, the output of production is feedback).
The main driver behind evaluating the “software supply chain” is to quickly retrieve the answer to three questions:
- What software do I have, including components that make up larger systems?
- When a piece of software or library is identified as vulnerable, does it affect me and if so, where?
How Can a JVM Manage My Java Applications’ Supply Chain?
There are many approaches used to inventory applications today. Custom software often uses tools to create SBOMs during the CI/CD pipeline; Maven provides this through its dependency:tree plugin. Another approach involves container scanning to analyze the wrapping environment in which the software runs. Another approach involves integrating agents into the software. Each approach though requires a team to act during a step in the supply chain and doesn’t catch production drift or downloaded items that are commonly deployed outside these steps. One of the unique vantage points possessed by the JVM is that it must be present everywhere to run the software and a JVM already has the necessary information because it’s responsible for loading the code.
Azul offers two JVMs that act as a drop-in replacement to other Java implementations. In addition to running applications faster and decreasing cost of operations, the October PSU release implements the first version of Vulnerability Detection to help deal with managing supply chain threats.
In the supply chain threat model, the JVM also offers another advantage of validating trust. As vendors and contractors produce their own SBOMs to identify components, from time to time that information may be incorrect. A contractor may shade a vulnerable library into their component assuming they’re being helpful by avoiding a namespace conflict. By using the JVM to generate and/or verify the SBOM, the component detection can be bytecode-aware. Instead of simply looking at files to determine what each file claims to be, the JVM can understand the “code shape” or signature and match components based on what they do rather than what they claim to be. Having worked in the Java community for over a decade of analyzing performance, Azul has created this cloud database of code recognition for performance and is able to apply the same approach to the security problem.
Augment Your Security Controls By Speeding Up Java
When the JVM does the work to track components, a key benefit is the ability to detect all workloads that run on the JVM, not just workloads that are engaged by security controls. Teams that are presently using other approaches to inventory components should continue to do so — the goal is defense-in-depth where each control works together to catch something the other could have missed. By working at production speed, newer technologies like Azul Vulnerability Detection are “shifting right” to offer production-speed verification of items that may have been missed, or to save work on integration and scanning every piece of Java software everywhere.