Avoid Native Calls

ID

java.avoid_native_calls

Severity

high

Resource

Api

Language

Java

Tags

CWE:246, NIST.SP.800-53, PCI-DSS:6.5.6

Description

Avoid native calls ('JNI').

Rationale

Calling native code from Java can introduce significant security risks and maintenance challenges.

Native methods can compromise Java’s platform independence and the built-in security mechanisms that the Java Virtual Machine (JVM) offers, such as memory safety and automatic garbage collection. Moreover, improper implementation of JNI can lead to vulnerabilities like buffer overflows, null pointer dereferences, and arbitrary code execution alongside difficulties in debugging and higher maintenance overhead due to varying behavior on different operating systems.

public class NativeExample {
    // Declaration of a native method
    public native void nativeMethod();

    static {
        // Load native library
        System.loadLibrary("NativeLib");
    }

    public static void main(String[] args) {
        new NativeExample().nativeMethod();
    }
}

Using such methods inadvertently creates attack vectors that can be exploited by malicious actors. Generally, it is advisable to minimize JNI usage and look for pure Java alternatives wherever feasible. JNI should only be used in scenarios where no other alternatives are available, and even then, it should be approached cautiously with strict security controls in place.

Remediation

To remediate the security risks associated with native method calls, consider the following best practices:

  1. Evaluate the Necessity: First, ascertain if the JNI invocation is absolutely necessary. Examine whether a Java equivalent exists that fulfills the same requirement without resorting to platform-specific code.

  2. Java Libraries and APIs: Leverage Java’s extensive range of built-in libraries and APIs, which often offer superior safety and portability compared to custom native code, avoiding the need to handle low-level system operations directly.

  3. Security Controls: If JNI must be used, implement rigorous security controls:

    • Validate all inputs diligently before passing them to native code to mitigate risks of buffer overflows or injections.

    • Encapsulate native calls within well-defined interfaces and limit their exposure to other parts of the application to minimize the attack surface.

  4. Code Reviews and Testing: Conduct thorough code reviews and extensive testing, particularly focusing on edge cases around data bounds and error handling to ensure robustness and safety of native interactions.

public class SaferJavaExample {
    public void javaEquivalentMethod() {
        // Implementation using Java's standard API
        System.out.println("Native method replaced with Java API equivalent.");
    }

    public static void main(String[] args) {
        new SaferJavaExample().javaEquivalentMethod();
    }
}

By following these remediation steps, applications can maintain their security posture and robustness while minimizing the risks associated with platform-specific native calls.

Configuration

The rule has the following configurable parameters:

  • allowedMethods, that indicates the list of fully qualified native methods that are allowed by this rule.