[
{"h1":"1 - Introduction"},
{"p":"The Java platform is broadly deployed on billions of devices, from servers and desktop workstations to consumer electronics. It was originallydesigned to implement an elaborate security model, the Java sandbox, thatallows for the secure execution of code retrieved from potentiallyuntrusted remote machines without putting the host machine at risk.Concretely, this sandboxing approach is used to secure the execution ofuntrusted Java applications such as Java applets in the web browser.Unfortunately, critical security bugs -- enabling a total bypass of thesandbox -- affected every single major version of the Java platform sinceits introduction. Despite major efforts to fix and revise the platform'ssecurity mechanisms over the course of two decades, critical securityvulnerabilities are still being found."},
{"p":"In this work, we review the past and present of Java insecurity. Our goalis to provide an overview of how Java platform security fails, such that wecan learn from the past mistakes. All security vulnerabilities presentedhere are already known and fixed in current versions of the Java runtime,we discuss them for educational purposes only. This case study has beenmade in the hope that we gain insights that help us design better systemsin the future."},
{"h1":"2 - Background"},
{"h2":"2.1 - A Brief History of Java Sandbox Exploits"},
{"p":"The first version of Java was released by Sun Microsystems in 1995 [2]. Oneyear later, researchers at Princeton University identified multiple flawsenabling an analyst to bypass the sandbox [3]. The authors identifiedweaknesses in the language, bytecode and object initialization, to name afew, some of them still present in Java at the time of writing. It is thefirst time a class spoofing attack against the Java runtime has beendetailed. A few years later, in 2002, The Last Stage of Delirium (LSD)research group presented their findings on the security of the Java virtualmachine [29]. They detailed vulnerabilities affecting, among others, thebytecode verifier and class loaders leading to type confusion or classspoofing attacks. In 2010, Koivu was the first to publicly show thattrusted method chain attacks work against Java by explaining how to exploitthe CVE-2010-0840 vulnerability he has found [32]. In 2011, Drake describedhow to exploit memory corruption vulnerabilities in Java [4]. He explainshow to exploit CVE-2009-3869 and CVE-2010-3552, two stack buffer overflowvulnerabilities. In 2012, Guillardoy [5], described CVE-2012-4681, twovulnerabilities allowing to bypass the sandbox. The first vulnerabilitygives access to restricted classes and the second allows to modify privatefields. Also in 2012, Oh described how to exploit the vulnerability ofCVE-2012-0507 to perform a type confusion attack to bypass the Java sandbox[6]. In 2013, Gorenc and Spelman performed a large scale study of 120 Javavulnerabilities and conclude that unsafe reflection is the most commonvulnerability in Java but that type confusion is the most common exploitedvulnerability [8]. Still in 2013, Lee and Nie identified multiplevulnerabilities including a vulnerability in a native method enabling thebypass of the sandbox [9]. Again in 2013, Kaiser described, among others,CVE-2013-1438 a trusted method chain vulnerability found by James Forshawand CVE-2012-5088 a Java reflection vulnerability found by SecurityExplorations. Between 2012 and 2013, security researchers at SecurityExplorations discovered more than 20 Java vulnerabilities [7]. Starting in2014, the developers of main web browsers such as Chrome or Firefox decidedto disable NAPI by default (hence no Java code can be executed by default)[11] [12]. The attack surface of Java being reduced, it seems that lessresearch on Java sandbox bypass is being conducted. However, exploitsbypassing the sandbox still pop up once in a while. For instance, in 2018,Lee describes how to exploit CVE-2018-2826, a type confusion vulnerabilityfound by XOR19 [18]."},
{"h2":"2.2 - The Java Platform"},
{"p":"The Java platform can be divided into two abstract components: the JavaVirtual Machine (JVM), and the Java Class Library (JCL)."},
{"p":"The JVM is the core of the platform. It is implemented in native code andprovides all the basic functionality required for program execution, suchas a bytecode parser, JIT compiler, garbage collector, and so forth. Due tothe fact that it is implemented natively, it is also subject to the sameattacks like any other native binary, including memory corruptionvulnerabilities such as buffer overflows [1], for example."},
{"p":"The JCL is the standard library that ships together with the JVM. Itcomprises hundreds of system classes, primarily implemented in Java, withsmaller portions being implemented natively. As all system classes aretrusted, they are associated with all privileges by default. Theseprivileges give them full access to any sort of functionality (filesystemread/write, full access to the network, etc.), and hence full access to thehost machine. Consequently, any security bug in a system class canpotentially be used by analysts to break out of the sandbox."},
{"p":"The main content of this paper is thus separated into two larger sections -one dealing with memory corruption vulnerabilities, and the other onefocussing on vulnerabilities at the Java level."},
{"h2":"2.3 - The Security Manager"},
{"p":"In the code of the JCL, the sandbox is implemented with authorizationchecks, most of them being permission checks. For instance, before anyaccess to the filesystem, code in the JCL checks that the caller has theright permission to access the filesystem. Below is an example checking theread permission on a file in class _java.io.FileInputStream_. Theconstructor checks that the caller has the read permission to read thespecified file on line 5."},
{"pre":" 1: public FileInputStream(File file) throws FileNotFoundException {\n 2: String name = (file != null ? file.getPath() : null);\n 3: SecurityManager security = System.getSecurityManager();\n 4: if (security != null) {\n 5: security.checkRead(name);\n 6: }\n 7: if (name == null) {\n 8: throw new NullPointerException();\n 9: }\n 10: if (file.isInvalid()) {\n 11: throw new FileNotFoundException(\"Invalid file path\");\n 12: }\n 13: fd = new FileDescriptor();\n 14: fd.incrementAndGetUseCount();\n 15: this.path = name;\n 16: open(name);\n 17: }"},
{"p":"Note that for performance reasons, authorizations are only checked if asecurity manager has been set (lines 3-4). A typical attack to escape theJava sandbox thus aims at setting the security manager to null. Thiseffectively disables all authorization checks. Without security managerset, the analyst can execute any code as if it had all authorizations."},
{"p":"However, authorizations are only checked at the Java level. Native codeexecutes with all authorizations. Although it might be possible to directlyexecute arbitrary analyst's controlled native code when exploiting memorycorruption vulnerabilities, in all the examples of this paper we focus ondisabling the security manager to be able to execute arbitrary Java codewith all permissions."}
]