Skip to content

Commit

Permalink
Fix Zip Slip Vulnerabilities (#2847)
Browse files Browse the repository at this point in the history
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: #2847
  • Loading branch information
lefou authored Oct 24, 2023
1 parent c4ec14e commit a3bd10c
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 3 deletions.
2 changes: 1 addition & 1 deletion ci/shared.sc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions main/api/src/mill/api/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {

Expand All @@ -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)
Expand Down

0 comments on commit a3bd10c

Please sign in to comment.