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

How are people avoiding name conflicts? #249

Closed
henniss opened this issue Apr 19, 2019 · 3 comments
Closed

How are people avoiding name conflicts? #249

henniss opened this issue Apr 19, 2019 · 3 comments

Comments

@henniss
Copy link

henniss commented Apr 19, 2019

My company uses a local instance running pypiserver to host our private projects. This has generally worked great... except this week someone registered a package with the same name as one of ours on PyPi, and their version number is higher, so pip defaults to installing it.

That's not their fault, of course, but it means we need to implement a better solution. Surely we're not the only ones who have dealt with this. What best practices have worked for people to avoid this?

Perhaps...

  1. Choosing names which begin with $ORG_NAME. This would probably solve the problem of random collisions, but doesn't solve the problem of an attacker uploading a targeted, malicious package.

  2. (1), together with name-squatting the corresponding names on pypi.org. PEP 541 seems to say that such empty projects are invalid will be removed from PyPi, though.

  3. Always run pip with --index-url=$OUR_REPO", and have a cron job which periodically mirrors all dependencies. (It seems like devpi-server supports something like this out of the box?)

  4. Maintain a requirements.txt and a requirements-local.txt for your projects, always install requirements.txt first, so that dependencies of your internal dependencies are already installed and you can run pip install -r requirements-local.txt --index-url=$OUR_REPO without needing to fetch dependencies from pypi.org?

Or something else?

@mplanchard
Copy link
Contributor

Glad to hear that things have been working out (mostly) well for you!

I'm not sure what other people are doing, but we used pypiserver for internal packages at a previous company, and we settled on an approach that was a bit of a hybrid of your suggestions:

  • name projects with the organization name
  • run pip with --index-url=$OUR_REPO

Because by default, pypiserver falls back to pypi.org if and only if only if the specified package is not found, the above strategy allows you to preferentially target your own packages while also getting other packages from PyPI.

The one corner case this doesn't quite cover is if one of the packages specified in your requirements file depends on a version of a package that is named the same as on of your organization's packages, but the org-specific naming should cover that case pretty solidly. For you to be targeted directly, you'd need to be a) installing a compromised requirement that b) specified a requirement that c) had the same name as one of your internal packages and d) had a higher version

If you're running pypiserver with the --disable-fallback option, I would recommend keeping separate requirements files, and then running, e.g.:

  • pip install -r requirements.txt
  • pip install --no-deps --force-reinstall -r requirements-local.txt --index-url=$OUR_REPO (install your packages without any of their dependencies from PyPI, and force reinstall just in case your public requirements pulled in a same-named package)
  • pip install --upgrade-strategy "only-if-needed" -r requirements-local.txt (ensure your local package's dependencies are installed from PyPI; won't override the install of your installed packages since they're already installed)

Let me know if I missed something!

@henniss
Copy link
Author

henniss commented Apr 25, 2019

Because by default, pypiserver falls back to pypi.org if and only if only if the specified package is not found,

Oh! That's exciting!

It looks like we're currently running an older version of Pypi server, 1.2.0, which tries to fall back on the old pypi domain. Because of that, I never noticed that it supported this fallback behavior. We just need to update our server and our pip.conf files and everything will just work.

Thanks for your help. I thought we'd need to go through and split up all our requirements files, but this is much simpler.

@henniss henniss closed this as completed Apr 25, 2019
@mplanchard
Copy link
Contributor

Awesome! Please don't hesitate to raise another issue if you run into any problems :)

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

No branches or pull requests

2 participants