Safeguard
Security

The Java Developer Kit Explained: Security Risks and How to Harden Your JDK

The Java Developer Kit is more than a compiler and runtime. Here is how to treat the JDK as part of your attack surface and keep it patched.

Marcus Chen
DevSecOps Engineer
6 min read

The Java Developer Kit (JDK) is a security-relevant component of your stack, not just a build tool, and treating it that way means tracking its version, patch level, and configuration the same way you track any dependency. The JDK ships the compiler (javac), the runtime (java), the standard library, and a large body of cryptographic and networking code. When a flaw lands in any of those, every application running on that runtime inherits it.

Teams that lock down their application dependencies but leave the JDK to drift are common. The runtime is where TLS negotiation, XML parsing, deserialization, and certificate validation actually happen, so an out-of-date JDK can undo a lot of careful work higher up the stack.

What the Java Developer Kit Actually Contains

The Java Developer Kit is the full development environment for the Java platform. It bundles the Java Runtime Environment (JRE), the compiler, debugging tools like jdb, packaging tools like jar, and the class libraries that make up the standard API. From a security standpoint the interesting parts are the built-in modules: java.net, javax.crypto, java.security, the JAXP XML stack, and the object serialization machinery.

Two things follow from that. First, the JDK version you deploy determines which cryptographic algorithms, TLS versions, and default security policies your app gets for free. Second, a vulnerability class like unsafe deserialization is a property of how you use the runtime, not a bug in it, so hardening is partly configuration and partly code.

Pick a Supported LTS Version

Java uses a long-term support (LTS) cadence. As of this writing, JDK 25 is the newest LTS release, made generally available on September 16, 2025, following JDK 21 (2023) and JDK 17 (2021). Oracle plans quarterly security and performance updates for JDK 25 through at least September 2028 under the No-Fee Terms and Conditions.

The practical rule: run a current LTS and take the quarterly Critical Patch Updates. Oracle publishes security fixes on a fixed quarterly schedule, and the release notes call out which CVEs each update addresses. If you are still on JDK 8 or 11, you are not necessarily insecure, but you are relying on extended support windows and missing years of hardening in the crypto and TLS defaults.

Check what you are actually running:

java -version
javac -version
# On a running JVM
jcmd <pid> VM.version

Distributions matter too. OpenJDK builds from Eclipse Temurin, Amazon Corretto, Azul Zulu, and Oracle all track upstream but ship on their own timelines. Standardize on one so your patch cadence is predictable.

Deserialization Is the Classic JDK Footgun

Java's native object serialization has been the source of a long line of remote code execution issues. The mechanism itself, ObjectInputStream.readObject(), will instantiate whatever class the byte stream names, and gadget chains in libraries on the classpath turn that into code execution.

The defensive posture is well established:

// Use a serialization filter to allow-list expected classes (Java 9+)
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
    "com.example.model.*;java.base/*;!*");
ObjectInputStream ois = new ObjectInputStream(in);
ois.setObjectInputFilter(filter);

Better still, avoid native serialization for untrusted input entirely. Prefer a data format like JSON with a parser you control, and never deserialize data that crossed a trust boundary without a strict filter. The JDK gained serialization filters precisely so teams could contain this risk without rewriting everything at once.

XML Parsing and XXE

The JAXP libraries inside the JDK parse XML, and XML External Entity (XXE) attacks let a malicious document read local files or make server-side requests. The fix is to disable external entity resolution on every parser factory you create:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

This is a code-level concern, but the parsers live in the JDK, so a runtime upgrade can change defaults. Test after upgrades rather than assuming behavior carries over.

Keep the Runtime and Its Dependencies in View

The JDK is one layer. The libraries you pull in through Maven or Gradle are another, and those are where most day-to-day vulnerabilities appear. A dependency like a JSON or XML library can carry a known CVE that the JDK cannot protect you from. This is where software composition analysis earns its place: an SCA tool such as Safeguard can flag a vulnerable transitive dependency in your pom.xml before it ships, and can also track which JDK base image a container is built on.

If you build container images, the base image usually pins the JDK. Rebuilding on a fresh, patched base image is often the fastest way to pick up JDK security fixes across a fleet. Automate that rebuild rather than doing it by hand.

Runtime Hardening Checklist

A few settings and habits pay off consistently:

  • Run with the least privilege the app needs; do not run the JVM as root in a container.
  • Keep TLS current. Newer JDKs disable weak protocols and cipher suites by default, which is a reason to stay current rather than override the defaults.
  • Use the java.security policy and module system to limit what code can do when you have a genuine sandboxing need.
  • Turn on serialization filters globally with jdk.serialFilter when you cannot patch every call site at once.
  • Monitor the Oracle Critical Patch Update advisories and your distribution's security feed, and wire those into your patch process.

For teams building a broader vulnerability-management practice around Java and other ecosystems, our security academy walks through prioritization and remediation workflows.

FAQ

Is the JDK the same as the JRE?

No. The JRE is the runtime needed to execute Java applications. The JDK is the full development kit and includes the JRE plus the compiler and developer tools. Modern Java distributions often ship only a JDK and let you create a slimmed runtime with jlink.

How often should I patch the Java Developer Kit?

Follow the quarterly Critical Patch Update schedule at a minimum, and apply out-of-band fixes for high-severity issues as they are announced. Staying on a supported LTS makes this sustainable because patches keep flowing.

Does upgrading the JDK break my application?

Major LTS jumps can introduce behavior changes, especially around removed APIs, TLS defaults, and the module system. Test in a staging environment, but the security cost of staying on an unsupported version usually outweighs the migration effort.

Can a vulnerability scanner detect JDK issues?

Yes. Container and dependency scanners can identify the JDK version in an image and match it against known CVEs, and SCA tools catch vulnerable Java libraries. Combine both for coverage of the runtime and the code running on it.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.