268
The following code defines a class named Echo. The class declares one native method (defined
below), which uses C to echo commands entered on the console back to the user. The following C
code defines the native method implemented in the Echo class:
Example Language: Java (Bad)
class Echo {
public native void runEcho();
static {
System.loadLibrary("echo");
}
public static void main(String[] args) {
new Echo().runEcho();
}
}
Example Language: C (Bad)
#include <jni.h>
#include "Echo.h"//the java class above compiled with javah
#include <stdio.h>
JNIEXPORT void JNICALL
Java_Echo_runEcho(JNIEnv *env, jobject obj)
{
char buf[64];
gets(buf);
printf(buf);
}
Because the example is implemented in Java, it may appear that it is immune to memory issues
like buffer overflow vulnerabilities. Although Java does do a good job of making memory operations
safe, this protection does not extend to vulnerabilities occurring in source code written in other
languages that are accessed using the Java Native Interface. Despite the memory protections
offered in Java, the C code in this example is vulnerable to a buffer overflow because it makes use
of gets(), which does not check the length of its input.
The Sun Java(TM) Tutorial provides the following description of JNI [See Reference]: The JNI
framework lets your native method utilize Java objects in the same way that Java code uses these
objects. A native method can create Java objects, including arrays and strings, and then inspect
and use these objects to perform its tasks. A native method can also inspect and use objects
created by Java application code. A native method can even update Java objects that it created or
that were passed to it, and these updated objects are available to the Java application. Thus, both
the native language side and the Java side of an application can create, update, and access Java
objects and then share these objects between them.
The vulnerability in the example above could easily be detected through a source code audit of the
native method implementation. This may not be practical or possible depending on the availability
of the C source code and the way the project is built, but in many cases it may suffice. However,
the ability to share objects between Java and native methods expands the potential risk to much
more insidious cases where improper data handling in Java may lead to unexpected vulnerabilities
in native code or unsafe operations in native code corrupt data structures in Java. Vulnerabilities
in native code accessed through a Java application are typically exploited in the same manner as
they are in applications written in the native language. The only challenge to such an attack is for
the attacker to identify that the Java application uses native code to perform certain operations.
This can be accomplished in a variety of ways, including identifying specific behaviors that are
often implemented with native code or by exploiting a system information exposure in the Java
application that reveals its use of JNI [See Reference].
MemberOf Relationships
CWE Version 4.14
CWE-112: Missing XML Validation
CWE-112: Missing XML Validation