Skip to content

Validate symlink targets during ZIP extraction to prevent path traversal#2667

Open
rm335 wants to merge 2 commits intoairbnb:masterfrom
rm335:fix/symlink-path-traversal-in-zip-extraction
Open

Validate symlink targets during ZIP extraction to prevent path traversal#2667
rm335 wants to merge 2 commits intoairbnb:masterfrom
rm335:fix/symlink-path-traversal-in-zip-extraction

Conversation

@rm335
Copy link

@rm335 rm335 commented Mar 12, 2026

Summary

  • Fix symlink path traversal vulnerability in the embedded ZipFoundation library used for .lottie (ZIP) extraction
  • Extracted file paths were validated via isContained(in:), but symlink targets were not — a malicious .lottie file could create symlinks pointing to arbitrary system files (e.g., /etc/passwd)
  • Add allowedDestination parameter to Archive.extract(_:to:...) and pass the destination directory from unzipItem, so symlink targets (both absolute and relative) are resolved and validated before creation

Test plan

  • Verify swift build succeeds (confirmed locally)
  • Create a test .lottie ZIP containing a symlink with an absolute target outside the extraction directory (e.g., /etc/passwd) and confirm extraction throws CocoaError(.fileReadInvalidFileName)
  • Create a test .lottie ZIP containing a symlink with a relative target escaping via ../../ and confirm extraction throws
  • Create a test .lottie ZIP containing a symlink with a valid relative target within the extraction directory and confirm extraction succeeds
  • Run existing unit/integration tests to verify no regressions

@calda
Copy link
Member

calda commented Mar 12, 2026

We don't want to manually modify any code under /EmbeddedLibraries/. Is there a newer version of ZIPFoundation that includes these changes that we can update to?

@rm335 rm335 force-pushed the fix/symlink-path-traversal-in-zip-extraction branch from ec20b7f to a6e9b04 Compare March 13, 2026 07:39
@rm335
Copy link
Author

rm335 commented Mar 13, 2026

Good call! The embedded ZIPFoundation was on 0.9.16, the symlink path traversal vulnerability was officially fixed upstream in 0.9.18 (CVE-2023-39138). I've updated the embedded source to 0.9.20 (latest) following the update instructions in the README, so the custom patch is no longer needed. This also picks up visionOS support, privacy manifest additions, and memory/resource leak fixes from 0.9.170.9.20.

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 this pull request may close these issues.

2 participants