{"id":82495,"date":"2026-07-24T12:46:25","date_gmt":"2026-07-24T09:16:25","guid":{"rendered":"https:\/\/afaghhosting.net\/blog\/cve-2026-63317-apache-opennlp-arbitrary-class-instantiation-in-generatorfactory-via-feature-descriptor-xml\/"},"modified":"2026-07-24T12:46:25","modified_gmt":"2026-07-24T09:16:25","slug":"cve-2026-63317-apache-opennlp-arbitrary-class-instantiation-in-generatorfactory-via-feature-descriptor-xml","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/cve-2026-63317-apache-opennlp-arbitrary-class-instantiation-in-generatorfactory-via-feature-descriptor-xml\/","title":{"rendered":"CVE-2026-63317 &#8211; Apache OpenNLP: Arbitrary Class Instantiation in GeneratorFactory via Feature Descriptor XML"},"content":{"rendered":"<p>CVE ID :CVE-2026-63317<\/p>\n<p>  Published : July 24, 2026, 9:16 a.m. | 33\u00a0minutes ago<\/p>\n<p>  Description :Arbitrary Class Instantiation via XML Feature Generator Descriptor and Format Name in Apache OpenNLP<\/p>\n<p>Versions Affected: <\/p>\n<p>&#8211; before 2.5.10<br \/>\n&#8211; before 3.0.0-M5<\/p>\n<p>Description: <\/p>\n<p>Three code paths in Apache OpenNLP load a class by its fully-qualified name via Class.forName() and invoke its no-arg constructor without any prior validation of the class name or its type.\u00a0<\/p>\n<p>The affected paths are: <\/p>\n<p>(1) GeneratorFactory, which reads the class attribute of generator elements in an XML feature generator descriptor; such descriptors are embedded as artifacts in model archives (e.g. TokenNameFinder and POSTagger models) and are parsed during model loading, so an attacker who can supply a crafted model archive controls the class name directly. <\/p>\n<p>(2) StreamFactoryRegistry.getFactory(Class, String), which falls back to interpreting an unregistered format name as the fully-qualified class name of an ObjectStreamFactory; this is exploitable in applications that pass untrusted format names (e.g. exposing the -format parameter of the command-line tooling to external input). <\/p>\n<p>(3) StringInterners, which instantiates the interner implementation named by the opennlp.interner.class system property; this value is normally deployer-controlled, so it is hardened as defense in depth rather than being independently attacker-reachable.<\/p>\n<p>Exploitation requires a class with attacker-useful side effects in its static initializer or no-arg constructor (JNDI lookup, outbound network I\/O, filesystem access) to be present on the classpath, so this is not drop-in remote code execution. T<\/p>\n<p>Mitigation: <\/p>\n<p>Upgrade to a fixed release. <\/p>\n<p>The fix routes all three paths through ExtensionLoader.instantiateExtension(&#8230;), which consults a package-prefix allowlist before Class.forName() is invoked, so a disallowed class is never loaded, initialized, or constructed.<br \/>\nClasses under the opennlp. prefix remain permitted by default. Deployments that load models referencing feature generator factories, object stream factories, or string interners outside opennlp.* must opt those packages in, either programmatically via ExtensionLoader.registerAllowedPackage(String) before the first model load, or by setting the OPENNLP_EXT_ALLOWED_PACKAGES system property to a comma-separated list of allowed package prefixes. <\/p>\n<p>Users who cannot upgrade immediately should ensure all model files and format names are sourced from trusted origins and should audit their classpath for classes with side-effecting static initializers or constructors.<\/p>\n<p>  Severity: 0.0 | NA<\/p>\n<p>  Visit the link for more details, such as CVSS details, affected products, timeline, and more&#8230;\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CVE ID :CVE-2026-63317 Published : July 24, 2026, 9:16 a.m. | 33\u00a0minutes ago Description :Arbitrary Class Instantiation via XML Feature Generator Descriptor and Format Name in Apache OpenNLP Versions Affected: &#8211; before 2.5.10 &#8211; before 3.0.0-M5 Description: Three code paths in Apache OpenNLP load a class by its fully-qualified name via Class.forName() and invoke its &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-82495","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/82495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=82495"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/82495\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=82495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=82495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=82495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}