CVE-2025-70952
Java vulnerability analysis and mitigation

Overview

CVE-2025-70952 is a path traversal (Zip Slip) vulnerability in the extract() function of Unzip.java in the pf4j (Plugin Framework for Java) library. It affects all versions of pf4j before commit 20c2f80 (corresponding to version 3.14.1), where improper handling of ZIP entry names allows directory traversal attacks due to insufficient path normalization and validation. The vulnerability was first reported in October 2025 (issue #618) and again in January 2026 (issue #623), with a patch committed and CVE published on March 25, 2026. It carries a CVSS v3.1 base score of 7.5 (High) (Red Hat CVE, GitHub Issue #618, GitHub Issue #623).

Technical details

The root cause (CWE-22) lies in the extract() method of org/pf4j/util/Unzip.java, which constructs file paths using new File(destination, zipEntry.getName()) — directly incorporating untrusted ZIP entry names — and then validates the result using String.startsWith() on canonical paths. This string-based prefix check has two known bypass vectors: (1) a sibling directory bypass where a destination of /tmp/zipSlip would incorrectly allow writes to /tmp/zipSlip_evil/ because the canonical path string starts with /tmp/zipSlip; and (2) a partial prefix match bypass where destination /tmp/dir would pass validation for paths resolving to /tmp/directory/file. Both bypasses allow a crafted ZIP archive to write files outside the intended extraction directory (Zip Slip attack). The fix replaces String.startsWith() with Java's Path.startsWith() after calling normalize().toAbsolutePath(), which performs proper path-component-level comparison (GitHub Issue #618, GitHub Issue #623, Patch Commit).

Impact

Successful exploitation allows an attacker to write arbitrary files to locations outside the intended extraction directory on the server's filesystem. This can lead to overwriting sensitive configuration files, deploying web shells or malicious scripts, or replacing application binaries — potentially resulting in remote code execution or persistent backdoor access. While the CVSS score reflects only availability impact (7.5 High), real-world Zip Slip exploitation typically enables full system compromise depending on the application context and file permissions of the process running pf4j (GitHub Issue #618, CVE Gist).

Exploitation steps

  1. Craft a malicious ZIP archive: Create a ZIP file containing an entry with a path-traversal name, such as ../zipSlip_evil/malicious.sh or ../../etc/cron.d/backdoor. Tools like Python's zipfile module or custom Java code can be used to embed such entry names that standard ZIP tools may not create.
  2. Identify a vulnerable pf4j deployment: Locate an application using pf4j versions prior to 3.14.1 (before commit 20c2f80) that accepts user-supplied or remotely-fetched ZIP/plugin archives for extraction.
  3. Deliver the malicious archive: Submit the crafted ZIP to the target application through any plugin upload, update, or installation mechanism that triggers pf4j's Unzip.extract() method.
  4. Bypass path validation: The vulnerable startsWith() check on canonical path strings fails to detect the traversal — for example, destination /tmp/zipSlip does not block writes to /tmp/zipSlip_evil/ because the string prefix matches.
  5. Achieve arbitrary file write: The malicious ZIP entry is extracted to the attacker-controlled path outside the destination directory, potentially overwriting scripts, configuration files, or deploying a web shell for subsequent remote code execution (GitHub Issue #618, GitHub Issue #623, Patch Commit).

Indicators of compromise

  • File System: Unexpected files written outside the designated plugin or extraction directory (e.g., scripts in /tmp/, /etc/cron.d/, web root directories, or application config paths); newly created files with names like malicious.sh or unexpected .jar/.sh files in sibling directories adjacent to the plugin extraction folder.
  • Logs: Application logs showing ZipException errors referencing "attempting to write outside the target directory" (patched versions) or unusual ZIP extraction activity; Java stack traces from org.pf4j.util.Unzip during plugin installation.
  • Process: Unexpected processes spawned by the Java application server process following a plugin installation or update event; unusual cron job execution or script activity shortly after ZIP extraction.
  • Network: Outbound connections from the application server to unknown external hosts following a plugin upload event, which may indicate post-exploitation activity (GitHub Issue #618, Patch Commit).

Mitigation and workarounds

Upgrade pf4j to version 3.14.1 or any release incorporating commit 20c2f80089d1ea779e22c2de5f109a0bce4e1b14, which replaces the flawed String.startsWith() canonical path check with Java's Path.startsWith() using normalize().toAbsolutePath() for proper path-component comparison. No configuration-based workaround is available; the fix requires a code change. As an interim measure, restrict the ability to upload or supply ZIP/plugin archives to trusted administrators only, and ensure the application process runs with the least privilege necessary to limit the impact of arbitrary file writes (Patch Commit, Red Hat CVE).

Community reactions

The vulnerability was discussed in two separate GitHub issues (#618 and #623) by independent researchers who identified the flawed startsWith() validation and proposed the normalized path fix. The pf4j maintainer (decebal) committed the fix addressing both issues. Red Hat tracked the CVE in their security advisory database. No significant broader media coverage or notable researcher commentary beyond the GitHub issues has been identified (GitHub Issue #618, GitHub Issue #623, Red Hat CVE).

Additional resources


SourceThis report was generated using AI

Related Java vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-p279-2cqp-84jgCRITICAL9.6
  • Java logoJava
  • org.openidentityplatform.opendj:opendj-server-legacy
NoYesJul 24, 2026
GHSA-fp43-vj7g-pg92HIGH7.5
  • Java logoJava
  • org.omnifaces:omnifaces
NoYesJul 24, 2026
GHSA-7ppr-r889-mcf2HIGH7.5
  • Java logoJava
  • org.http4s:http4s-blaze-server_2.12
NoYesJul 24, 2026
GHSA-mhvj-jhpq-885vHIGH7.4
  • Java logoJava
  • org.http4s:http4s-blaze-server_2.13
NoYesJul 24, 2026
GHSA-46q4-43ph-c6frHIGH7.4
  • Java logoJava
  • org.http4s:blaze-http_2.12
NoYesJul 24, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management