Skip to content

Security: Zip Slip path traversal in user data pack import may allow file creation outside the intended directory #41

Description

@hl72425

During a source-code-based review of open-source Unity projects, we identified a potential Zip Slip path traversal issue in the user data pack import logic of MinecraftVsZombies2Unity.

The issue appears in the user data pack zip import flow. The application allows a user to select a zip file, validates the presence of metadata.json, and then extracts entries under the userdata/ prefix into the user save directory. However, the current implementation only checks whether the first path segment is userdata; it does not normalize and validate the final destination path before writing the file.

Dangerous data flow

The dangerous data flow is approximately:

User selects an external zip file via UI
-> MainmenuController.OnImportPathSelected(path)
-> SaveManager.ImportUserDataPackMetadata(path)
-> metadata.json validation succeeds
-> SaveManager.ImportUserDataPack(userName, userIndex, path)
-> iterates ZipArchive.Entries
-> uses entry.FullName to construct destination path
-> Path.Combine(userDir, relativePath)
-> File.Open(destPath, FileMode.CreateNew)
-> writes attacker-controlled file content

A crafted user data pack may contain an entry such as:

userdata/../../mvz2_zip_slip_marker.txt

When imported, this entry may escape the intended user save directory and create an attacker-controlled file in a parent directory such as Application.persistentDataPath.

In this scenario, the attacker does not need prior access to the victim’s file system; the victim only needs to import a crafted user data pack.

Impact

Based on the current source code, we have not confirmed a direct RCE chain.

The most accurate impact statement at this stage is:

Path traversal during user data pack import may allow file creation outside the intended extraction directory.

However, similar game-content import path traversal issues are security-relevant. For example, NVD’s CVE-2026-50663 describes insufficient path restrictions when processing crafted game scenario content, potentially allowing files to be written outside the intended directory and leading to more severe impact.

We therefore recommend addressing this issue proactively.

Suggested remediation

  1. Normalize each zip entry path before use.
  2. Reject entries containing .., absolute paths, drive-letter paths, or NUL bytes.
  3. Resolve the final destination with Path.GetFullPath.
  4. Ensure the final destination remains inside the intended user data directory.
  5. Perform validation before creating directories or writing files.
  6. Add regression tests for unsafe and safe entries, including:
userdata/../../x
userdata/..\..\x
/absolute/path
C:\temp\x
userdata/valid/file.txt

Example defensive pattern

var root = Path.GetFullPath(userDir);

if (!root.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
    root += Path.DirectorySeparatorChar;
}

var normalized = relativePath.Replace('\\', '/');

if (normalized.Contains('\0') ||
    normalized.StartsWith("/") ||
    normalized.Contains(":") ||
    normalized.Split('/').Any(part => part == ".."))
{
    throw new InvalidDataException($"Unsafe zip entry path: {relativePath}");
}

var target = Path.GetFullPath(Path.Combine(root, normalized));

if (!target.StartsWith(root, StringComparison.OrdinalIgnoreCase))
{
    throw new InvalidDataException($"Zip entry escapes extraction root: {relativePath}");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions