Skip to content

Security: .arcpkg import allows Zip Slip path traversal and writes files outside the import directory #97

Description

@hl72425

Summary

ArcCreate imports .arcpkg files as ZIP archives. During extraction, the importer combines FileStatics.TempImportPath with ZipArchiveEntry.FullName and writes the resulting path with File.OpenWrite.

Because the entry name is not canonicalized and checked against the intended extraction root, an archive entry such as ../arc_zip_slip_marker.txt can escape the Temporary/import directory.

Confirmed impact: arbitrary file write within the application's permissions.

Confirmed contextual impact: on platforms where Application.persistentDataPath/Temporary/import is the extraction root and Application.persistentDataPath/Macros is the macro directory, a crafted entry such as ../../Macros/arc_zip_slip_probe.lua can place a Lua macro file into ArcCreate's macro autoload directory. MacroService.Awake() calls ReloadMacros(), which scans MacroDefFolder and executes each .lua file through LuaRunner.RunScript(...).DoString(...).

Suggested fix

Resolve the intended root and candidate output path with Path.GetFullPath() and verify that the candidate path remains under the intended root before creating directories or writing files.

Example:

string root = Path.GetFullPath(FileStatics.TempImportPath);
root = root.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
    + Path.DirectorySeparatorChar;

string entryName = entry.FullName.Replace("\\", "/");
string candidate = Path.GetFullPath(Path.Combine(root, entryName));

if (!candidate.StartsWith(root, StringComparison.Ordinal))
{
    throw new InvalidDataException("Archive entry escapes import directory: " + entry.FullName);
}

string parent = Path.GetDirectoryName(candidate);
if (!string.IsNullOrEmpty(parent))
{
    Directory.CreateDirectory(parent);
}

using (FileStream fs = File.OpenWrite(candidate))
using (Stream zs = entry.Open())
{
    zs.CopyTo(fs);
}

It may also be useful to explicitly reject absolute paths, drive-qualified paths, UNC paths, and normalized paths containing parent-directory traversal.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions