{
  "entrypoint_kind": "function_call",
  "entrypoint_detail": "opennlp.tools.ml.libsvm.doccat.SvmDoccatModel.deserialize(InputStream) fed a crafted HashMap<String,double[8000000]> payload (allow-listed classes, within all numeric limits) on the FIXED build (opennlp-3.0.0-M4, 3cf42d4a)",
  "service_started": true,
  "healthcheck_passed": true,
  "target_path_reached": true,
  "target_path_detail": "Reached SvmDoccatModel.deserialize -> ois.setObjectInputFilter(buildFilter) -> ois.readObject() (line 271) -> ObjectInputStream.readObject -> HashMap.readObject -> readArray on the fixed build; filter ALLOWED the stream; OutOfMemoryError thrown during array allocation in readObject.",
  "runtime_stack": ["openjdk-21.0.11", "maven-3.9.12", "opennlp-ml-libsvm 3.0.0-SNAPSHOT (built from 3cf42d4a / opennlp-3.0.0-M4)", "zlibsvm-core 3.0.0", "libsvm 3.35", "slf4j"],
  "variant_target_commit": "3cf42d4a0145cefd9dd06138873a91312052c767",
  "variant_target_release": "opennlp-3.0.0-M4",
  "reproduces_on_fixed": true,
  "reproduces_on_vulnerable": true,
  "bypass_type": "denial_of_service_memory_exhaustion",
  "filter_outcome_fixed_small_heap": "OutOfMemoryError during ObjectInputStream.readObject()/HashMap.readObject()/readArray (NOT InvalidClassException -> filter allowed the stream)",
  "filter_outcome_fixed_large_heap": "ClassCastException after full 256MiB allocation (NOT InvalidClassException -> filter allowed the stream; cast fails only after readObject completes)",
  "fix_primary_goal_holds": true,
  "fix_primary_goal_runtime_evidence": "fixed_rce run: MaliciousGadget stream -> InvalidClassException: filter status: REJECTED, no marker. vuln_rce run: MaliciousGadget stream -> [GADGET EXECUTED] + marker created.",
  "impact_class": "denial_of_service",
  "original_cve_impact_class": "code_execution",
  "impact_parity": "partial",
  "proof_artifacts": [
    "logs/vuln_variant/fixed_oom_small.log",
    "logs/vuln_variant/fixed_oom_large.log",
    "logs/vuln_variant/vuln_oom_large.log",
    "logs/vuln_variant/fixed_rce.log",
    "logs/vuln_variant/vuln_rce.log",
    "logs/vuln_variant/gadget_executed_vuln_variant.txt",
    "logs/vuln_variant/fixed_version.txt",
    "logs/vuln_variant/vulnerable_version.txt"
  ],
  "notes": "DoS bypass confirmed on the fixed build via three consecutive runs (all exit 0). The OOM is triggered DURING deserialisation (stack: ObjectInputStream.readArray -> Array.newInstance, called from HashMap.readObject, called from SvmDoccatModel.deserialize:271), proving the filter's allow-list + numeric limits do not bound total memory. No RCE bypass: all allow-listed classes are plain data types with no exploitable serialization hooks; the foreign-gadget RCE control is rejected on the fixed build."
}
