Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

local security vulnerability: all ports visible to any local user. #688

Closed
ivanov opened this Issue · 9 comments

4 participants

@ivanov
Owner

Maybe there's already a place somewhere in the documentation, but I did not find it.

This was reported and 'exploited' by @philipn in this vim-ipython pull request: ivanov/vim-ipython#2

Basically, any local user can just ps ax | grep IPython to get all of the port numbers used by another user's IPython instance.

I looked into the issue, and one way to hide this information from other users would be to pass the arguments as environment variables. They will still be visible using ps -e to the user who started IPython, but not to other users. Though this was/is a bug in Solaris, http://osvdb.org/24200 - where any user could see everyone's environment variables. Does this sound reasonable?

@minrk
Owner

This is described in the parallel security doc, which is really identical to the kernel model except that the kernel, for now, elects not to use the extra HMAC validation used in the parallel code.

Essentially, IPython is not safe on untrusted localhost. This is a fundamental limitation of using zeromq. The HMAC signing does protect you from unauthorized execution, but it is perfectly impossible to protect you from snooping PUB traffic.

Hiding the ports from the command-line does make it the tiniest bit less trivial to exploit, but not significantly less secure. I don't think environment variables are the way to go, but using the private (chmod 600-style) connection-files pattern used by the parallel code would have a similar effect, without polluting the environment.

@takluyver
Owner

I think the connection files would be a usability win as well. At present connecting more than one frontend to a kernel requires copying and pasting arguments to the command line, and if I start the Qt console without a terminal, I don't know how to get that information. If there were connection files in the profile directory, it could be arranged so that ipython qtconsole --existing would seek out the most recently started kernel to connect to.

@philipn

@minrk Is there protection from authorized execution? That document (and you'll have to pardon me, I'm not familar with the kernel model or what that means) says "to protect users of shared machines, [HMAC] digests are used to sign messages, using a shared key"

So if I know the command line parameters are , say, --existing --shell=47439 --iopub=54051 --stdin=45340 --hb=52506, can't I connect and execute arbitrary code as any machine user?

@minrk
Owner

@philipn yes, there is protection, no it is not on by default (nor is it particularly useful yet outside the parallel code).

The two-process IPython kernel+frontend used in the qtconsole / vim integration is what I referred to as the kernel model. The communication code is identical to what is used in my IPython.parallel. One feature it has, to protect from unauthorized execution, is signing messages with HMAC digests using a shared-key. This is because it is simply impossible in zeromq to protect against unauthorized connections, so there is no way to prevent unauthorized incoming messages from users with access to localhost ports. This signature means that messages from clients that don't have the shared key can be safely ignored. This is really no help against DoS, though.

The kernel (again, the backend for vim/qt) has simply not yet decided to turn on HMAC digests by default, so it currently has no protection against unauthorized execution. Switching to the connector-file model used in the parallel code will make using these digests trivial.

You can activate the digests right now, by simply specifying Session.keyfile in the command-line or ipython_config.py. An easy example it to just use your ssh key, e.g.:

ipython qtconsole --Session.keyfile=$HOME/.ssh/id_rsa

but any private textfile will do.

I tried this, and while it does protect against unauthorized execution, the kernel hasn't been updated to be aware of the feature, so the error just raises, and the kernel shuts down when an invalid message arrives. An easy fix, though.

@takluyver
Owner

@minrk: Incidentally, if I've understood what's going on correctly, the warning in the docs "...it would be trivial for an attacker to intercept messages and deduce the key" is somewhat overstated. Even with MD5, which is the default hashing for HMAC, a preimage attack is far from 'trivial'.

@minrk
Owner

@takluyver - yet another case of me letting the docs slip out of date. For a long time the 'signature' was just a UUID, so if you sniffed one message, you could spoof it trivially. This is no longer true after switching to HMAC digests.

@minrk
Owner

see #689 for the tiny fixes needed for the kernel to be robust against unauthorized or garbage messages. With this, simply specify Session.keyfile, and you are set.

@philipn

@takluyver I agree about the connection file. This is what I was trying to do with my command-line sniffing :)

Sounds like turning on that Session.keyfile bit by default / updating the kernel would be a good idea.

@minrk
Owner

@philipn yes, that's always been the plan, but various other things have taken priority. We will definitely get this done by 0.12.

@minrk minrk referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@minrk minrk referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@minrk minrk referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@minrk minrk referenced this issue from a commit in minrk/ipython
@minrk minrk use connection files instead of ports to connect to kernels
this addresses security issues (#688)
and ease-of-multi-frontend
ebac3b1
@minrk minrk closed this issue from a commit
@minrk minrk Merge PR #847 (connection files)
* JSON connection files are now used to connect files
* HMAC message signing is now on by default in all IPython apps
* Adds IPython.lib.kernel, which contains utility functions for connecting
  clients. These were mostly copied out of qtconsoleapp in order to be
  more general.
* Adds %connection_info and %qtconsole magics to zmqshell

closes gh-688
closes gh-806
closes gh-691
f93a8ca
@minrk minrk closed this in f93a8ca
@ellisonbg ellisonbg referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@ellisonbg ellisonbg referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@mattvonrocketstein mattvonrocketstein referenced this issue from a commit in mattvonrocketstein/ipython
@minrk minrk use connection files instead of ports to connect to kernels
this addresses security issues (#688)
and ease-of-multi-frontend
678e67e
@mattvonrocketstein mattvonrocketstein referenced this issue from a commit in mattvonrocketstein/ipython
@minrk minrk Merge PR #847 (connection files)
* JSON connection files are now used to connect files
* HMAC message signing is now on by default in all IPython apps
* Adds IPython.lib.kernel, which contains utility functions for connecting
  clients. These were mostly copied out of qtconsoleapp in order to be
  more general.
* Adds %connection_info and %qtconsole magics to zmqshell

closes gh-688
closes gh-806
closes gh-691
906733a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.