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

Fix #3907 tar file placed outside of target location #6313

Merged
merged 2 commits into from
Sep 26, 2019

Conversation

wilsonfv
Copy link
Contributor

@wilsonfv wilsonfv commented Mar 3, 2019

Add a warning if one of the tar file will be placed outside of target location causing potential security issue.

Fixes #3907.

@pradyunsg pradyunsg added S: awaiting response Waiting for a response/more information S: needs triage Issues/PRs that need to be triaged labels Mar 5, 2019
@cjerdonek
Copy link
Member

If we detect a file being written outside of the location, I think we should fail rather than warn.

@wilsonfv
Copy link
Contributor Author

If we detect a file being written outside of the location, I think we should fail rather than warn.

we could fail it immediately, i am just not sure if its a bug or a design issue so just a warning in case i break anything

we could roll out this changes if no further complain, we can then fail it in next release
what do you think @cjerdonek

@pradyunsg pradyunsg removed the S: awaiting response Waiting for a response/more information label Mar 12, 2019
Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of making this an error message now and then breaking behavior in the future.

@cjerdonek
Copy link
Member

Since this is broken behavior and also a security issue, I think we should simply prevent this from happening if we're already going to the trouble of detecting it. Also, if you read the original report, it said,

pip processes invalid packages .tar/.zip archives containing "../" directory traversal chars and places package files outside of target directories even after pip complains and throws errors and aborts the install.

Especially if pip is already erroring out, it seems like it doesn't really help things to log a warning in addition to the error. Pip is already throwing an error.

@cjerdonek
Copy link
Member

By the way, when I asked about possible backwards compatibility concerns on the original issue, I was also thinking about things like paths that might resolve to something within the target directory, but that contained ... In other words, we don't just want to rule out any path that contains ... Resolving the path and collapsing occurrences of .. (as this PR does) before doing a path comparison to see if it lies outside of the target directory addresses that backwards compatibility issue I was concerned about.

@xavfernandez
Copy link
Member

Since this is broken behavior and also a security issue, I think we should simply prevent this from happening if we're already going to the trouble of detecting it.

I agree.

@pradyunsg
Copy link
Member

Since this is broken behavior and also a security issue, I think we should simply prevent this from happening if we're already going to the trouble of detecting it.

Let's do this then. :D

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Mar 15, 2019
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Mar 16, 2019
@cjerdonek
Copy link
Member

One thing I would like to see as part of this PR is a helper function to create a zip file containing files with given paths.

Then, there can be two tests of unzip_file() side-by-side: one testing a zip file whose paths are all okay, and one testing a zip file with a path that would go outside the target directory. Only the latter should fail, and it should fail with the right error message.

And similarly for a tar file.

I think this would provide better assurance that the check is working correctly than just testing the correctness of a helper function used inside unzip_file() and untar_file().

@wilsonfv
Copy link
Contributor Author

One thing I would like to see as part of this PR is a helper function to create a zip file containing files with given paths.

Then, there can be two tests of unzip_file() side-by-side: one testing a zip file whose paths are all okay, and one testing a zip file with a path that would go outside the target directory. Only the latter should fail, and it should fail with the right error message.

And similarly for a tar file.

I think this would provide better assurance that the check is working correctly than just testing the correctness of a helper function used inside unzip_file() and untar_file().

this is now a breaking behavior
and unit test cases have been added. The added test.zip and test.tgz files contain .. path

@cjerdonek
Copy link
Member

I had suggested creating a helper function to create the zip and tar files, and also including the success case and not just the failure case. I think it’s better not to check in binary files, especially if it’s easy to avoid.

@wilsonfv
Copy link
Contributor Author

I had suggested creating a helper function to create the zip and tar files, and also including the success case and not just the failure case. I think it’s better not to check in binary files, especially if it’s easy to avoid.

The existing test_unpack_tgz and test_unpack_zip already validate the successful cases

@cjerdonek
Copy link
Member

Not with the helper function I’m suggesting that you create. I think it’s important to have a test case to show that the zip files it creates are valid. It won’t even be any extra work. Just calling the same test function but with a different input argument.

@wilsonfv
Copy link
Contributor Author

Not with the helper function I’m suggesting that you create. I think it’s important to have a test case to show that the zip files it creates are valid. It won’t even be any extra work. Just calling the same test function but with a different input argument.

Sorry, I am not sure what you mean. There seems to be no existing test case that creates a zip file
Could you point me to the source code you are referring to

@cjerdonek
Copy link
Member

Yes, that’s why I said the function needs to be created. Python’s zipfile module provides that ability: https://docs.python.org/3/library/zipfile.html

@cjerdonek cjerdonek added type: bug A confirmed bug or unintended behavior type: security Has potential security implications and removed S: needs triage Issues/PRs that need to be triaged labels Mar 17, 2019
@wilsonfv
Copy link
Contributor Author

Yes, that’s why I said the function needs to be created. Python’s zipfile module provides that ability: https://docs.python.org/3/library/zipfile.html

We have prepared the zip files in the data package for the test cases. I do not see creating a zip file at run time make any difference

@cjerdonek
Copy link
Member

There are a number of differences. Some of the advantages of doing it at runtime are — We don’t need to check in binary files, which I want to avoid if we can. There’s no easy way for reviewers to review the contents of a binary file or know by looking at it what properties it has. It’s harder to update a binary file if we need to make changes to it. Binary also makes it harder to create more test cases: with runtime you can test whatever paths or properties you need to very easily. For example, maybe we want to test different types of characters in the file names in addition to “..”, or paths containing “..” that resolve to inside the target. There are different test cases even with this particular bug alone.

@wilsonfv
Copy link
Contributor Author

wilsonfv commented Apr 6, 2019

@cjerdonek @pradyunsg please review changes

@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Aug 4, 2019
@wilsonfv wilsonfv force-pushed the master branch 2 times, most recently from d1b33ae to 7365cff Compare August 11, 2019 15:44
Copy link
Member

@chrahunt chrahunt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I'm missing something - I see several comments and some discussion about zip file test helpers and other higher-level tests (which is what I was going to comment on for this PR), but the diff for all commits only shows tests of is_within_directory. Is this expected, or are there tests/changes missing?

@cjerdonek
Copy link
Member

Hmm, I seem to remember there being issues with some of the rebases. The code from before isn't present anymore. :( @wilsonfv, do you have your old commits? If not, we could try to help you restore those using Git's reflog.

@cjerdonek
Copy link
Member

Some portions of the previous code are visible if you click to expand the (outdated) comments of the previous iterations.

@chrahunt
Copy link
Member

If you expand the unchanged sections of test_utils.py in the commit diff here it shows the tests I think are now missing.

@wilsonfv
Copy link
Contributor Author

If you expand the unchanged sections of test_utils.py in the commit diff here it shows the tests I think are now missing.

@chrahunt this has been added back, thanks for checking

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Aug 22, 2019
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Aug 22, 2019
@nicferrier
Copy link

Guys? can you please merge this? pip is continually blocked by security tooling because of this silly little bug.

It will make a lot of people's live's easier if it's merged before poor Wilson has to do another load of work to keep the PR in line!

Thanks!

Copy link
Member

@chrahunt chrahunt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. 👍 Just a few very minor style comments.

Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code change looks fine to me -- I second @chrahunt's style change suggestions.

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Sep 18, 2019
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Sep 25, 2019
@chrahunt
Copy link
Member

Rebased and addressed review comments. IMO this can be merged once the checks pass.

@chrahunt
Copy link
Member

I reviewed the existing comments and believe all of them have been addressed, so I will merge this. If I missed anything, we can definitely address it in a follow up.

Thanks @wilsonfv for your time and patience. :) We greatly appreciate your contribution.

@chrahunt chrahunt merged commit ea923d9 into pypa:master Sep 26, 2019
@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Oct 27, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation type: bug A confirmed bug or unintended behavior type: security Has potential security implications
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pip processes corrupt packages containing using ../ chars placing files outside target directory
8 participants