Skip to content

`ZipSecurity` is vulnerable to partial-path traversal vulnerability

Moderate
nahsra published GHSA-qh4g-4m4w-jgv2 Feb 1, 2024

Package

maven io.github.pixee:java-security-toolkit (Maven)

Affected versions

<=1.1.1

Patched versions

1.1.2

Description

Summary

ZipSecurity#isBelowCurrentDirectory is vulnerable to a partial-path traversal bypass.

Impact

To be vulnerable to the bypass, the following conditions must all be met:

  • Applications that uses toolkit version <=1.1.1
  • Applications that uses ZipSecurity as a guard against path traversal
  • Applications that have a exploit path

Although the control still protects attackers from escaping the application path into higher level directories (e.g., /etc/), it will allow "escaping" into sibling paths.

For example, if your running path is /my/app/path you an attacker could navigate into /my/app/path-something-else.

Details

See:

boolean isBelowCurrentDirectory(final File fileWithEscapes) throws IOException {
final File currentDirectory = new File("");
String canonicalizedTargetPath = fileWithEscapes.getCanonicalPath();
String canonicalizedCurrentPath = currentDirectory.getCanonicalPath();
return !canonicalizedTargetPath.startsWith(canonicalizedCurrentPath);
}

This method is vulnerable because currentDirectory.getCanonicalPath() returns a string that is not terminated by a trailing slash. As such, using startsWith to do string comparisons opens up a weakness allowing for partial-path traversal into a sibling directory.

PoC

This vulnerability is described in detail in Jonathan Leitschuh's Black Hat talk: https://youtu.be/zTtbVxGEq8A?si=Nmt0aGpPnSPrzTxi

Assume that the working directory for the given Java process is a directory named code-sandbox. The following test demonstrates escaping that directory.

    @Test
    void pixeeZipGuardBypass() throws IOException {
        File bypass = new File("../code-sandbox-sibling/bypass");
        assertTrue(isBelowCurrentDirectory(bypass), "The attacker provided value escaped the intended directory!");
    }

    boolean isBelowCurrentDirectory(final File fileWithEscapes) throws IOException {
        final File currentDirectory = new File("");
        String canonicalizedTargetPath = fileWithEscapes.getCanonicalPath();
        String canonicalizedCurrentPath = currentDirectory.getCanonicalPath();
        return !canonicalizedTargetPath.startsWith(canonicalizedCurrentPath);
    }

Credit

Thanks to Jonathan Leitschuh for discovering and reporting the vulnerability.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
Low
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N

CVE ID

CVE-2024-24569

Weaknesses

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. Learn more on MITRE.

Credits