You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import Foundation
import ZIPFoundation
letfileManager=FileManager()varsourceURL=URL(fileURLWithPath:"/path/to/payload.zip")vardestinationURL=URL(fileURLWithPath:"/path/to/")do{try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes:nil)try fileManager.unzipItem(at: sourceURL, to: destinationURL)}catch{print("Extraction of ZIP archive failed with error:\(error)")}
Expected Results
secret.txt is extracted to the target extraction directory
Actual Results
secret.txt is extracted to the parent of target extraction directory
Technical details
the package uses the following function to check that the zip entry path is located within the extraction directory:
func isContained(in parentDirectoryURL:URL)->Bool{// Ensure this URL is contained in the passed in URLletparentDirectoryURL=URL(fileURLWithPath: parentDirectoryURL.path, isDirectory: true).standardized
returnself.standardized.absoluteString.hasPrefix(parentDirectoryURL.absoluteString)}
However, when provided with the following path /base_path/extraction_directory//../ the path gets normalized to /base_path/extraction_directory/entry_file_name which passes the check above.
when that same path is passed to fopen, it gets normalized to /base_path/entry_file_name.
letdestinationRepresentation= fileManager.fileSystemRepresentation(withPath: url.path)
guard let destinationFile:FILEPointer=fopen(destinationRepresentation,"wb+")else{throwCocoaError(.fileNoSuchFile)}
The text was updated successfully, but these errors were encountered:
Summary
Path parsing confusion between URL from Foundation package and fopen function, leading to path traversal.
Steps to Reproduce
1- Generate
payload.zip
using the following code:2- Extract
payload.zip
usingunzipItem
Expected Results
secret.txt
is extracted to the target extraction directoryActual Results
secret.txt
is extracted to the parent of target extraction directoryTechnical details
the package uses the following function to check that the zip entry path is located within the extraction directory:
However, when provided with the following path
/base_path/extraction_directory//../
the path gets normalized to/base_path/extraction_directory/entry_file_name
which passes the check above.when that same path is passed to
fopen
, it gets normalized to/base_path/entry_file_name
.The text was updated successfully, but these errors were encountered: