Inheritance and Security
I recently started migrating my organization from localshop to devpi, which seems to be a much more active project. Thank you to everyone who has and continues to contribute. I'm worried about what I consider a security risk when using devpi as a repository for private python packages, using pypi.python.org as the attack vector. I'd like to start a discussion with this community with the hopes of determining if my fear is well founded, and what possible solutions we can implement going forward. If a legitimate package *x* is uploaded to a private devpi index at version *n*, and an illegitimate package *x* is uploaded to pypi.python.org with a version >*n*, then it is possible that your deployment scripts, or setup.py of packages dependent on* x* will install the illegitimate package instead of the intended package. All the attacker would need to know is the package name, and possibly the version depending on how strict your dependencies are defined to pwn your system. I have thought of two possible solutions to this problem, the first being secure by default and the second insecure by default, but at least security is possible. *Secure By Default* Simply don't use inheritance on packages that exist in the child index. If *x* exists in child index then don't include *x* from the parent index. I haven't used a complicated inheritance scheme, and I don't know if others are, but this could be reduced to only excluded packages from *root/pypi*. This is also the simplest solution, but also could be disruptive depending on how you are using devpi. I can't think of a case when I personally would want both *root/pypi* and my private versions of a package included in the same index, but that's not to say it's not a valid use case for others. Valid permutations of this solution would be allowing inheritance of existing packages to be toggled per index. This is the solution I'd like to see implemented. I actually have a (probably insufficient) implementation of this solution at https://bitbucket.org/doki_pen/devpi. The change is very simple<https://bitbucket.org/doki_pen/devpi/commits/33630707a73a0aff422f757f462bf6459abcd043> . *Secure By Configuration* The other idea is less elegant and harder to implement, blacklisting inherited modules per index. This would involved extending the api to allow modules to be added to and removed from the blacklist on a per index bases. The advantage to this solution is that it would be less disruptive to any existing implementations of devpi.
Hi Bob, first of all i think your analysis is right, there is a problem where attackers could exploit dependencies on private packages where malicious packages are uploaded to root/pypi, unless you generally pin versions. On Thu, Nov 14, 2013 at 11:00 -0800, Bob Corsaro wrote:
I recently started migrating my organization from localshop to devpi, which seems to be a much more active project. Thank you to everyone who has and continues to contribute.
I'm worried about what I consider a security risk when using devpi as a repository for private python packages, using pypi.python.org as the attack vector. I'd like to start a discussion with this community with the hopes of determining if my fear is well founded, and what possible solutions we can implement going forward.
If a legitimate package *x* is uploaded to a private devpi index at version *n*, and an illegitimate package *x* is uploaded to pypi.python.org with a version >*n*, then it is possible that your deployment scripts, or setup.py of packages dependent on* x* will install the illegitimate package instead of the intended package. All the attacker would need to know is the package name, and possibly the version depending on how strict your dependencies are defined to pwn your system.
Right.
I have thought of two possible solutions to this problem, the first being secure by default and the second insecure by default, but at least security is possible.
*Secure By Default* Simply don't use inheritance on packages that exist in the child index. If *x* exists in child index then don't include *x* from the parent index. I haven't used a complicated inheritance scheme, and I don't know if others are, but this could be reduced to only excluded packages from *root/pypi*. This
Agreed, we should only think about excluding root/pypi not any other index at this point.
is also the simplest solution, but also could be disruptive depending on how you are using devpi. I can't think of a case when I personally would want both *root/pypi* and my private versions of a package included in the same index, but that's not to say it's not a valid use case for others. Valid permutations of this solution would be allowing inheritance of existing packages to be toggled per index.
This is the solution I'd like to see implemented. I actually have a (probably insufficient) implementation of this solution at https://bitbucket.org/doki_pen/devpi. The change is very simple<https://bitbucket.org/doki_pen/devpi/commits/33630707a73a0aff422f757f462bf6459abcd043>
I like the solution because it doesn't require any addition of UI. But it may be too limited for the cases where you are preparing a new release that is going to be eventually pushed to pypi.python.org. Specifically, before the upload all release files are visible. Afterwards only the uploaded version will be available. If installation scripts work against this index and want to install another non-dev version, they will fail. Also people using "tox" (http://tox.testrun.org) might have test configurations that test both dev and production versions of a package. Typically those test runs use a single index (i do in my projects). Introducing a new "shadowing" behaviour would break them, i am afraid.
*Secure By Configuration*
The other idea is less elegant and harder to implement, blacklisting inherited modules per index. This would involved extending the api to allow modules to be added to and removed from the blacklist on a per index bases. The advantage to this solution is that it would be less disruptive to any existing implementations of devpi.
One problem i see with devpi-server is that it does not allow to have per-project configuration. If we had per-project configuration, then adding a flag "private" would be easy and it would mean that root/pypi is never asked about this project (maybe except to report clashes because that may be good to know in any case). Having per-project configuration would also help to add metadata like its repository-url, a bugtracker page, a Jenkins-Job page or other interesting per-project data (classically this info is partially kept in distribution/package files themselves but i think this is sub-optimal). I think the per-project config is the cleaner solution but it is more work. Uploaded packages for not-yet-configured projects would probably default to "private" if no root/pypi one exists and to "public" if it does. This would be shown prominently on the upload. If it's the first time you upload something and you see that devpi-server treats it as public but you want to have it private, it means that you should think of a non-clashing name to begin with. The main problem with per-project config is that it seems to be rather a global (per devpi-server) thing than a per-index one. So we would need a new /project/X endpoint i think and probably a "devpi project" command line subcommand to show/manage settings. If "X" is a project on root/pypi then you would not be able to change the settings much, i guess. These are just my current thoughts. Happy about more comments on the topic or other solutions. best, holger
-- You received this message because you are subscribed to the Google Groups "devpi-dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to devpi-dev+...@googlegroups.com. To post to this group, send email to devp...@googlegroups.com. Visit this group at http://groups.google.com/group/devpi-dev. For more options, visit https://groups.google.com/groups/opt_out.
participants (2)
-
Bob Corsaro
-
holger krekel