Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createTempJarFile method has a zipslip that causes arbitrary file writes #344

Open
808Mak1r opened this issue Oct 11, 2024 · 0 comments
Open

Comments

@808Mak1r
Copy link

808Mak1r commented Oct 11, 2024

Describe the bug
A possible Zip Slip vulnerability exists in the code.Zip Slip is a vulnerability that exploits insecure path manipulation, which allows an attacker to achieve arbitrary file writes by constructing a specific zip file and writing the file to an arbitrary path, including a sensitive or system path, when unzipping it.

To Reproduce
In the following code

File output = createTempJarFile(input, jarEntry.getName());
The method createTempJarFile is called in

    static JarFile getNestedJarFile(URL url) throws IOException {
        StringSequence spec = new StringSequence(url.getFile());
        Map<String, JarFile> cache = fileCache.get();
        JarFile jarFile = (cache != null) ? cache.get(spec.toString()) : null;

        if (jarFile != null) {
            return jarFile;
        } else {
            jarFile = getRootJarFileFromUrl(url);
        }

        int separator;
        int index = indexOfRootSpec(spec);
        if (index == -1) {
            return null;
        }
        StringSequence entryName;
        if ((separator = spec.indexOf(SEPARATOR, index)) > 0) {
            entryName = spec.subSequence(index, separator);
        } else {
            entryName = spec.subSequence(index);
        }
        JarEntry jarEntry = jarFile.getJarEntry(entryName.toString());
        if (jarEntry == null) {
            return null;
        }
        try (InputStream input = jarFile.getInputStream(jarEntry)) {
            File output = createTempJarFile(input, jarEntry.getName());
            jarFile = new JarFile(output);
            addToRootFileCache(url.getPath(), jarFile);
        }

        return jarFile;
    }

In the function createTempJarFile

private static File createTempJarFile(InputStream input, String outputName) throws IOException {

    private static File createTempJarFile(InputStream input, String outputName) throws IOException {
        File dir;
        String fName = (new File(outputName)).getName();
        if (fName.length() < outputName.length()) {
            String localDir = outputName.substring(0, outputName.length() - fName.length());
            Path path = Paths.get(TMP_FILE.getPath() + File.separatorChar + localDir);
            dir = Files.createDirectories(path).toFile();
        } else {
            dir = TMP_FILE;
        }
        File f = new File(dir, fName);
        f.deleteOnExit();
        try (FileOutputStream outputStream = new FileOutputStream(f)) {
            copy(input, outputStream);
        }

        return f;
    }

Fix
Fixing this vulnerability requires stricter validation and normalization of the outputName to ensure that it does not contain any malicious path fragments (e.g., ..) . This can be fixed using the following method:

  1. Validate and normalize the path: ensure that the outputName does not contain a sequence of path traversal characters (e.g. ..) .
  2. Handle paths safely: Use safe path splicing methods and avoid splicing strings directly.
...
    // check outputName,make sure it doesn't contain a sequence of path traversal characters
    if (outputName.contains("..")) {
        throw new IOException("Invalid output name: " + outputName);
    }
...
    if (fName.length() < outputName.length()) {
        String localDir = outputName.substring(0, outputName.length() - fName.length());
        Path path = TMP_FILE.toPath().resolve(localDir).normalize(); // Safe handling of paths with resolve and normalize
        if (!path.startsWith(TMP_FILE.toPath())) { // Ensure that the path is not outside the intended directory
            throw new IOException("Invalid output directory: " + path);
        }
        dir = Files.createDirectories(path).toFile();
    } else {
        dir = TMP_FILE;
    }
...

Expected behavior

Version
easeagent-v2.2.8

Configuration

Logs

OS and Hardware

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant