Vulnerability: Arbitrary File Write in adm-zip Versions of `adm-zip` before 0.4.9 are vulnerable to arbitrary file write when used to extract a specifically crafted archive that contains path traversal filenames (`../../file.txt` for example).


## Recommendation

Update to version 0.4.9 or later.
Vulnerability ID: GHSA-3v6h-hqm4-2rg6
CWE: CWE-22
Severity score: 0
Project: https://github.com/cthackers/adm-zip
Published: 2018-07-27
File: adm-zip.js
Commit message: Merge pull request #212 from aviadatsnyk/master

fix: prevent extracting archived files outside of target path.  Credit to Snyk Security Research Team for disclosure and fixing the issue.
Commit author: The Brain

Vulnerable version (before fix):
 module.exports = function(/*String*/input) {               var target = pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName));              if (item.isDirectory) {                 target = pth.resolve(target, ".."); module.exports = function(/*String*/input) {             _zip.entries.forEach(function(entry) {                 entryName = entry.entryName.toString();                  if(isWin){                     entryName = escapeFileName(entryName)                 } module.exports = function(/*String*/input) {                     entryName = escapeFileName(entryName)                 }                  if (entry.isDirectory) {                     Utils.makeDir(pth.resolve(targetPath, entryName));                     if(--i == 0)

Fixed version (after fix):
 module.exports = function(/*String*/input) {               var target = pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName));             if(!target.startsWith(targetPath)) {                 throw Utils.Errors.INVALID_FILENAME + ": " + entryName;             }              if (item.isDirectory) {                 target = pth.resolve(target, ".."); module.exports = function(/*String*/input) {             _zip.entries.forEach(function(entry) {                 entryName = entry.entryName.toString();                  if(!pth.resolve(targetPath, entryName).startsWith(targetPath)) {                     throw Utils.Errors.INVALID_FILENAME + ": " + entryName;                 }                  if(isWin){                     entryName = escapeFileName(entryName)                 } module.exports = function(/*String*/input) {                     entryName = escapeFileName(entryName)                 }                  if(!pth.resolve(targetPath, entryName).startsWith(targetPath)) {                   throw Utils.Errors.INVALID_FILENAME + ": " + entryName;                 }                  if (entry.isDirectory) {                     Utils.makeDir(pth.resolve(targetPath, entryName));                     if(--i == 0)

Patch:
patch: @@ -354,6 +354,9 @@ module.exports = function(/*String*/input) {
 
 
             var target = pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName));
+            if(!target.startsWith(targetPath)) {
+                throw Utils.Errors.INVALID_FILENAME + ": " + entryName;
+            }
 
             if (item.isDirectory) {
                 target = pth.resolve(target, "..");
@@ -429,6 +432,10 @@ module.exports = function(/*String*/input) {
             _zip.entries.forEach(function(entry) {
                 entryName = entry.entryName.toString();
 
+                if(!pth.resolve(targetPath, entryName).startsWith(targetPath)) {
+                    throw Utils.Errors.INVALID_FILENAME + ": " + entryName;
+                }
+
                 if(isWin){
                     entryName = escapeFileName(entryName)
                 }
@@ -471,6 +478,10 @@ module.exports = function(/*String*/input) {
                     entryName = escapeFileName(entryName)
                 }
 
+                if(!pth.resolve(targetPath, entryName).startsWith(targetPath)) {
+                  throw Utils.Errors.INVALID_FILENAME + ": " + entryName;
+                }
+
                 if (entry.isDirectory) {
                     Utils.makeDir(pth.resolve(targetPath, entryName));
                     if(--i == 0)
path: adm-zip.js