pypa / pip

The Python package installer
https://pip.pypa.io/
MIT License
9.51k stars 3.02k forks source link

pip should not execute arbitrary code from the Internet #425

Closed glyph closed 11 years ago

glyph commented 12 years ago

When you 'pip install' something, it fetches the code from the internet, and then executes it. If you follow the advice of many projects and 'sudo pip install' something, pip executes that code from the internet as root.

pip does not do TLS certificate verification, nor does it do package signature verification, nor does it even do DNSSEC. There is no assurance whatsoever that the code being installed came from the intended source. The archetypical hipster hacker doing a 'pip install django' over some cafe's wifi will be pwned within seconds if the DNS for pypi.python.org happens to be spoofed.

I believe that this might be addressed by https://github.com/pypa/pip/pull/402 but that deals with a bunch of other issues as well, and I felt there should be a report somewhere about this somewhat well-known deficiency in pip's download and update procedures.

westurner commented 11 years ago

Though, I must point out -- as others have on this ticket -- that the following are separate issues:

Documentation links from here, reddit (2), [...] :

PEPs

JSON metadata (pymeta.json, pymeta-dependencies.json) is generated from setup.py ... http://hg.python.org/peps/file/default/pep-0426/pymeta-schema.json

Python

PIP

Setuptools

Distlib

Narrative Documentation

Glossaries

Reddit threads:

tag: https://en.wikipedia.org/wiki/DevOps

westurner commented 11 years ago

https://python-packaging-user-guide.readthedocs.org/en/latest/packaging_tutorial.html#create-your-first-release

Source Repository GPG

Python Package GPG (./<package>.asc)

For any archive downloaded from an index, you can retrieve any signature by just appending .asc to the path portion of the download URL for the archive, and downloading that.

Python Wheel JWS S/MIME (PEP 427)

Index Mirror DSA (PEP 381)

[Cryptographic] Hash Functions

x-post to #1035

dstufft commented 11 years ago

I'm going to close this ticket as it has no clear goal. Pip no longer downloads things from PyPI without TLS.

If there are specific deficiencies with what pip offers per item tickets should be opened for each one.

radiosilence commented 11 years ago

Also could I point out that doing sudo pip install is something you should never do? Either install --local, user a virtualenv, or use a system package manager for installing things systemwide.

dstufft commented 11 years ago

Using sudo pip install is fine. Not all systems with sudo even have a package manager or often times the system package manager is very outdated or missing that item all together.

pip vs OS packages is a user choice with various trade offs to both sides of the argument.

radiosilence commented 11 years ago

If your system doesn't have a package manager, why not use a virtualenv?

If you are using a system with any kind of package manager, you should never sudo pip install, because then you are messing with a file structure that is supposed to be managed with the package manager, and say a system component requires a specific version of something, you are going to get file conflicts and all kinds of hell.

If a system-wide package requires a python component, the dependency should be resolved with the package manager. If not, virtualenv.

I don't think it is a personal choice, because it's a terrible habit and I've seen many systems get screwed up due to it by people who are making a "user choice" and have no idea the implications of what they are doing. If you are using, say, OSX for development, use a virtualenv, if you are creating a distributable package, then use brew (or whatever) to install Python dependencies (and if brew doesn't have the package, change that by making a brew package).

For instance - I want to run uWSGI as a system-wide daemon. The version of uWSGI in my package manager (let's say Debian wheezy) is totally out of date. So, I create a virtualenv in /opt/uwsgi and install it there, then have my init script reference /opt/uwsgi/bin/uwsgi, and don't fuck up my system.

It's just being responsible.

dstufft commented 11 years ago

If my system doesn't have a package manager how am I supposed to install virtualenv ;) Also needing to activate a virtualenv for using command line tools is ugly.

I don't know what Linux systems you use, but in my preferred Debian based ones sudo pip install installs to /usr/local which, as far as I understand the FHS, is outside of the domain of the system package manager and is intended for just such use.

radiosilence commented 11 years ago

Ok, makes sense - though I would explicitly check your distro does this first. But then, what's the problem with doing pip install --user and then adding ~/.local/bin to your $PATH?

dstufft commented 11 years ago

It's only available to my user :) Get's annoying when I'm bouncing between different accounts for different things.

westurner commented 11 years ago

AFAIK, sudo pip install (like every other unchecked source of executable code) should not be run as root on an actual system. Debian mitigates around this with fakeroot and virtual containers for building packages. Files built are signed and checksummed.

If pip dropped privs to the minimum it needs to install into a path in PATH and sys.path, it would still be a risk to execute sudo pip install.

Could someone indicate to me how live.sysinternals.com is more or less of a risk than just 'sudo rm *'?

Don't open (executable) email attachments. Don't sudo pip install.

westurner commented 11 years ago

I like virtualenv and virtualenvwrapper alot. I like not having write permission to scripts that I execute often (e.g. --user).

Does pip support --prefix? Does pip do snapshots/backups prior to installation?

merwok commented 11 years ago

how am I supposed to install virtualenv

You don’t have to: just download virtualenv.py and run it. From that first venv, you can get pip, venvwrapper, etc. Yes, it’s per-user.

needing to activate a virtualenv for using command line tools is ugly.

I add the bin directory of the bootstrap venv I describe above to my PATH.

radiosilence commented 11 years ago

Also, perhaps one could avoid depending on pip --user (which I find irritating) by running virtualenv ~/.local

westurner commented 11 years ago

Also, perhaps one could avoid depending on pip --user (which I find irritating) by running virtualenv ~/.local

For the sake of consistency, a mkvirtualenv local and a symlink to $VIRTUAL_ENV/local make it easier to work with virtualenvwrapper.

merwok commented 11 years ago

I’m not sure consistency is an argument here. The venvs that I manage with virtualenvwrapper are used for my Python projects and can be deleted or re-created at all time, but the global/bootstrap venv I created in ~/.usr (or ~/local in your example) is not throw-away: I depend on having things installed in there (mostly scripts/programs, not libs).

westurner commented 11 years ago

This is way OT. To each their own. I should have been more clear. I believe consistency to be an argument here because I like to consistently apply the same tools and processes to managing virtual environments. Commands like cpvirtualenv, cdvirtualenv, and cdsitepackages are not present with a (special-cased) plain-old virtualenv.

When I backup a virtualenv, I usually only need the pip freeze and contents of ./src. When I backup a homedir, I usually don't want to copy compiled, version-specific objects into a backup archive. (So I install scripts/programs as a dotfiles egg with a ./scripts folder and/or [console_scripts] entrypoints in setup.py.)

nejucomo commented 11 years ago

I consider the discussion about user permissions and install locations when running pip to be orthogonal to this ticket, which is about TLS verification. So, I created #1169 to capture that orthogonal issue.