Chief Scientist Emeritus Fabian Yamaguchi and foundational Code Property Graph technology recognized with IEEE Test of Time Award

Java was originally designed with security in mind, which makes its present-day reputation for being insecure unfortunate. Yet it is probably inevitable that the flaws of a twenty-five-year-old language would be discovered and exploited. Especially with a language like Java which still ranks among the top three most popular programming languages today.

Java is not the most insecure programming language enjoying widespread use, but it makes that top three list as well, according to recent research. These poor security rankings come in spite of the considerable security features integrated in the development of Java and available through libraries. For example, Java security libraries offer:

  • Strong data typing
  • Automatic memory management
  • Bytecode verification
  • Secure class loading

Java was designed with the security weaknesses of C and C++ in mind, and actively engineered to improve upon their shortcomings. Highly vulnerable processes like memory deallocation were offloaded to automated garbage collection rather than left in the hands of developers. Other unsafe constructs were left out of Java, or modified to execute more securely — forced index checking before accessing arrays, for example. In a broad attempt to remediate coding errors in general, enforced exception catching was built into the compiler.

Yet despite the hard work done by Oracle and others to secure the platform, well-known features of Java remain insecure.

Why Is Java Insecure?

One contributing factor of Java’s insecurity lay with the Java Virtual Machine (JVM) which is required to handle faulty byte code. Java is also vulnerable to insecurities embedded in trusted code or to user input which may maliciously subvert it through injection attacks. Java apps importing vulnerabilities from buggy open-source components is another problem, one which impacts an estimated 97% of test cases.

Five Tips for Securing Java Apps

Writing a bullet-proof Java app would be a daunting, if not impossible task. However, many Java apps can become considerably more secure by following a few simple guidelines. Taking a few small steps to harden a Java app against cyber threats is well worth the long-term benefits of releasing a robust program. Devs interested in ensuring their Java apps are more secure than average should consider the following five tips:

Clear Sensitive Data

One easy way to secure Java apps is by clearing sensitive data after use. Leaving high-value data like encryption keys, personally identifiable information (PII), or user credentials for garbage collection exposes them to potential danger. For example, users with the same access rights as the Java application may be able to read sensitive data before it is destroyed. Remote attackers could use Heartbleed, the buffer over-read bug in Open SSL to access lingering information. Firewire or Thunderbolt ports are also vulnerable to DMA attacks that could expose sensitive data in memory.

Non-cleared data also risks being saved to the disk. This could happen if the host system enters hibernation mode, if memory becomes too full, or if the app crashes and core dumps. Once sensitive data is written to the disk, it is vulnerable to dumpster-dive attacks. However, all of these attack vectors can be mitigated by clearing sensitive data the moment it is no longer needed by the app.

Minimize or Avoid Object Deserialization

Deserialization has proven to be a persistent and serious problem for Java. Deserialization occurs after an object is serialized (converted to a bit stream), transferred, and then recreated as an object.

1 Java object serialization, transfer, and deserialization.

The problem occurs when the JVM deserializes, or restores, the bit stream back to an object. If the JVM picks the correct type of object during the restoration process then all is well. However, attackers can create opportunities for exploitation by making the JVM translate bit streams into the wrong type of objects. Some deserialization exploits allow remote code execution, making them a serious security threat.

The best way to avoid this vulnerability is to simply not use deserialization at all. Learning to code in Java without using serialization may ultimately prove worthwhile as there is serious discussion over removing the feature altogether.

Prevent Code Injections

Code injections come in many forms, but generally operate using the same basic principles:

  • Attackers supply malicious input to a program, often as a command or query
  • The bad input is processed by an interpreter
  • The interpretation of the malicious data alters the execution of the program to the benefit of the attackers

One effective technique for fighting code injections is sanitizing a user’s input by making it conform to a whitelist of acceptable characters. This prevents malicious actors from including executable input or other characters that might subvert the program through the interpreter.

XML external entity (XXE) attacks targeting the XML interpreter are another popular form of injection attack against Java. One well-known example is the Billion Laughs attack. This denial of service attack uses a self-referential, exponentially growing, malicious XML entity created through Document Type Definitions (DTD), see Figure 2.

2 Example of the Billion Laughs XXE exploit, using XML with DTD

XXE attacks can be stopped by making sure input conforms to specific lengths and formats, whitelisting, or by disallowing DTDs. Blocking the expansion of entities is another viable solution.

Never Accept Unauthorized File Uploads

If a Java app accepts files it is important to ensure it rejects malicious, untrusted, and unauthorized uploads. Making sure a file matches the expected file type goes a long way towards preventing security problems. For example, if an app calls for an image file it should check to make sure nothing containing executable code is accepted. There are several ways to check file contents ranging from simple file name verification, to magic number testing, to completely parsing the file. While a balance must be struck between file analysis and overall app performance, stronger verification processes will inevitably lead to better security.

Perform App Security Testing Throughout the SDLC

Building a secure Java app is easier when effective application security testing is integrated throughout the SDLC. Two particularly useful testing methods that work well during development are next-generation static application security testing (NG-SAST) and intelligent SCA.

Benefits of ShiftLeft CORE’s NG-SAST

ShiftLeft CORE’s NG-SAST improves upon traditional SAST by leveraging the power of the code property graph (CPG) to shorten testing times and improve results. The CPG is a joint data structure that combines information from abstract syntax trees, control flow graphs, and program dependency graphs. This allows the CPG to rapidly detect attackable paths in custom code.

3 The Code Property Graph (CPG) combines three representations of source code into a versatile joint data structure

When compared to traditional static testing, NG-SAST using CPGs achieved a 100% true positive rate and performed 45% better than average in OWASP tests.

Benefits of ShiftLeft CORE’s Intelligent SCA

Software composition analysis (SCA) is a useful technique for determining if an app is relying on libraries with known vulnerabilities. Java apps, as well as 96% of other applications, use open-source components that may contain vulnerabilities.

However, it is possible for applications to use vulnerable components in a way that makes them unreachable by attacker-controlled inputs. ShiftLeft CORE’s Intelligent SCA (I-SCA) not only identifies known vulnerabilities in packages, but it uses attackability to determine if flaws are reachable by threat actors. By objectively analyzing risk exposure, intelligent SCA can save developers time by ensuring they only mitigate issues that are exploitable.

Interested In Java Application Security Testing?

To see how attackability provides high context security findings for Java early in the development cycle, create a free account at https://www.shiftleft.io/register.

About Qwiet AI

Qwiet AI empowers developers and AppSec teams to dramatically reduce risk by quickly finding and fixing the vulnerabilities most likely to reach their applications and ignoring reported vulnerabilities that pose little risk. Industry-leading accuracy allows developers to focus on security fixes that matter and improve code velocity while enabling AppSec engineers to shift security left.

A unified code security platform, Qwiet AI scans for attack context across custom code, APIs, OSS, containers, internal microservices, and first-party business logic by combining results of the company’s and Intelligent Software Composition Analysis (SCA). Using its unique graph database that combines code attributes and analyzes actual attack paths based on real application architecture, Qwiet AI then provides detailed guidance on risk remediation within existing development workflows and tooling. Teams that use Qwiet AI ship more secure code, faster. Backed by SYN Ventures, Bain Capital Ventures, Blackstone, Mayfield, Thomvest Ventures, and SineWave Ventures, Qwiet AI is based in Santa Clara, California. For information, visit: https://qwiet.ai

Share