From a3bd10c7e22c8f9287b9e88eee0faee4d67288c9 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Tue, 24 Oct 2023 10:48:31 +0200 Subject: [PATCH] Fix Zip Slip Vulnerabilities (#2847) Specially prepared zip archives with crafted entries containing relative paths may result in overwritten files outside the destination directory. By using `os.SubPath`, we detect and fail in such cases. Pull request: https://github.com/com-lihaoyi/mill/pull/2847 --- ci/shared.sc | 2 +- main/api/src/mill/api/IO.scala | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ci/shared.sc b/ci/shared.sc index 72e0133ae5c..57bb0eec30f 100644 --- a/ci/shared.sc +++ b/ci/shared.sc @@ -20,7 +20,7 @@ def unpackZip(zipDest: os.Path, url: String) = { case null => false case entry => if (!entry.isDirectory) { - val dest = zipDest / os.RelPath(entry.getName) + val dest = zipDest / os.SubPath(entry.getName) os.makeDir.all(dest / os.up) val fileOut = new java.io.FileOutputStream(dest.toString) val buffer = new Array[Byte](4096) diff --git a/main/api/src/mill/api/IO.scala b/main/api/src/mill/api/IO.scala index 9c2e3cba0ab..01521bb1364 100644 --- a/main/api/src/mill/api/IO.scala +++ b/main/api/src/mill/api/IO.scala @@ -13,7 +13,10 @@ object IO extends StreamSupport { * @param ctx The target context * @return The [[PathRef]] to the unpacked folder. */ - def unpackZip(src: os.Path, dest: os.RelPath = os.rel / "unpacked")(implicit + def unpackZip( + src: os.Path, + dest: os.RelPath = os.rel / "unpacked" + )(implicit ctx: Ctx.Dest ): PathRef = { @@ -24,7 +27,7 @@ object IO extends StreamSupport { case null => false case entry => if (!entry.isDirectory) { - val entryDest = ctx.dest / dest / os.RelPath(entry.getName) + val entryDest = ctx.dest / dest / os.SubPath(entry.getName) os.makeDir.all(entryDest / os.up) val fileOut = new java.io.FileOutputStream(entryDest.toString) IO.stream(zipStream, fileOut)