Apache OpenNLP Arbitrary Class Instantiation via Model Manifest
Overview
The ExtensionLoader.instantiateExtension method in Apache OpenNLP versions prior to 2.5.9 and 3.0.0-M3 is vulnerable to arbitrary class instantiation. An attacker can craft a malicious model archive containing a modified manifest.properties file. This manifest can specify a fully-qualified class name that will be loaded by Class.forName(). While OpenNLP performs a type check after loading, the class is already loaded and initialized by Class.forName() before this check occurs. This means that if the specified class has side effects in its static initializer (e.g., JNDI lookups, network I/O, file system access), these effects will execute regardless of whether the class ultimately passes the type check. This allows an attacker to potentially execute arbitrary code or cause denial of service if a vulnerable class with such side effects is present on the classpath and the attacker can control the model archive loaded. This risk is amplified in scenarios where models are loaded from untrusted sources.
Affected Systems
Testing Guide
1. Identify if your deployment uses Apache OpenNLP. 2. Check the specific version of Apache OpenNLP being used. 3. If the version is before 2.5.9 (for 2.x branch) or before 3.0.0-M3 (for 3.x branch), you are potentially affected. 4. For a more definitive check, attempt to load a model archive with a crafted `manifest.properties` file pointing to a known class with side-effecting static initializers (e.g., a test class that performs a `System.out.println` or a simple network connection on initialization) and observe if these side effects occur during model loading. 5. Verify if any mitigation strategies (like package allowlisting or trusting model sources) are already in place.
Mitigation Steps
* Upgrade Apache OpenNLP to version 2.5.9 or later for 2.x, or to 3.0.0-M3 or later for 3.x. * Configure an allowlist of trusted package prefixes using `ExtensionLoader.registerAllowedPackage(String)` or the `OPENNLP_EXT_ALLOWED_PACKAGES` system property, consulting it before `Class.forName()` is invoked. * Ensure all model files are sourced exclusively from trusted origins. * Audit the application's classpath for classes with potentially malicious static initializers or no-arg constructors that perform sensitive operations.
Patch Details
2.5.9, 3.0.0-M3