-
-
Notifications
You must be signed in to change notification settings - Fork 391
fix: prevent extraction of archived files outside target path #65
Conversation
I'll add a test next week, but if you can't wait, the idea is to extract the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have just one request, that we consolidate all the zip-slip logic into a single function which we then call from the individual extractors.
zip.go
Outdated
destpath := filepath.Join(destination, zf.Name) | ||
if !strings.HasPrefix(destpath, destination) { | ||
return fmt.Errorf("%s: illegal file path", zf.Name) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this logic could be pulled into its own function so that we don't have to repeat it everywhere? It's simple, I know, but it would be nice to standardize it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a stab at it. Let me know what you think.
I'm not sure about the name sanitizeExtractPath
, so if you have any idea - that could be great.
Excellent. I'm not too picky about that name, I think it's good. Thank you for contributing this! A test would definitely be good to have, so if you have the time, I think that'd be important. Thanks ;) |
The fix is insufficient because you can use symlinks in
I'm not sure what a good fix would be, as symlinks are a feature of PS: Symlinks are theoretically also supported by edit: sorry, just noticed that there is already an open issue about that #69 |
@mholt if you need snyk's help with this - we're happy to chip in :D |
I would love some help. Been too busy to maintain this lately. Would anyone be able to commit a little time to improve this lib? I will make you a collaborator. :) |
could you please review #70 ? |
Can you confirm this fix is in golang 10.3? |
cancel that, this is a separate project |
How this work with following files? destination = "/foo/bar" extracted file = "/foo/bar/../../../../etc/hosts" I don't make sure but you have to call filepath.Clean() before checking. |
@mattn the fix for the issue you're describing has already been merged - this is what this PR solved. |
@aviadatsnyk do you mean this PR solve my comment? https://github.com/mholt/archiver/pull/65/files
This condition possibly pass insecure paths. destination = "/foo/bar" |
that is what I meant. |
Ah, I missed it. |
Why this PR?
This PR is meant to fix an arbitrary file write vulnerability, that can be achieved using a specially crafted zip archive, that holds path traversal filenames. When the filename gets concatenated to the target extraction directory, the final path ends up outside of the target folder.
A sample malicious zip file named zip-slip.zip. (see this gist) was used, and when running the code below, resulted in creation of
evil.txt
file in /tmp folder.There are various possible ways to avoid this issue, some include checking for
..
(dot dot) characters in the filename, but the best solution in our opinion is to check if the final target filename, starts with the target folder (after both are resolved to their absolute path).Stay secure,
Snyk Team