I want to disable disable the shell (! CMD) and magic commands (% CMD) from the notebook to prevent users running shell commands within a notebook. How to do this?
You could probably make a custom kernel that doesn't support that extra syntax, but it doesn't work as a security measure - normal Python code can do anything you can do with a shell command. If you're trying to protect the system from users, it's a better bet to run users' notebook servers in containers (e.g. using Docker).
I run jupyterhub on Docker. I changed my users shell to a limited one (lshell). The jupyter terminal opens the lshell but the users can still run sh commands within the notebook (the shell backend seems to be setup to /bin/sh). Ideally, I would like that backend to be setup to lshell as well. Is it possible?
At present, no, but I think we'd probably accept a PR for that to follow the $SHELL environment variable. The relevant code is here: https://github.com/ipython/ipython/blob/master/IPython/utils/_process_posix.py#L61
@naileakim unless you are running a heavily modified IPython, users are going to be able to run shell commands via Python APIs, e.g. subprocess.Popen(['bash', '-c', '...']). Locking down ! doesn't prevent execution of arbitrary code.
If you want to only disable !, you can override the system method on the InteractiveShell object:
In [11]: !ls
files
In [12]: get_ipython().system = lambda *args: print('! is disabled!')
In [13]: !ls
! is disabled!
Is there a way to filter (regex etc) before running the code in a cell ? If that is so, we can apply a patch and see if the user is trying any imports relevant to os/system.
Locking down Python that way is really hard, because it's a very flexible language and there are a lot of ways around simple restrictions. E.g. if you block import os, I might still be able to do __import__('os'). There are a lot of things like that, and trying to lock them all down will probably make it very hard to do anything useful.
If you want to provide Python execution for untrusted users, a better way is to do it in some kind of container or VM sandbox, and then let them run any code they want.
Thanks for your response @takluyver
Yeah, locking down that way would be hard. The problem I'm facing is that I can't dockerize/containerize it because I need to configure it for an enterprise, and several access / bureaucratic issues if I go down that route.
In my case, luckily the end users would be people with less programming background and hub service won't be exposed to the outside world. So I was thinking of doing some patching (regex etc on the code) before it even runs !
To do so, any ideas which files I could modify ? Any help would be highly appreciated !
I really don't recommend that. Regex-munging code is not going to give you any meaningful security, and it's going to be an annoying mess to maintain. Sorry, but I'm not going to provide instructions for something that seems very clearly a bad idea.
Most helpful comment
I really don't recommend that. Regex-munging code is not going to give you any meaningful security, and it's going to be an annoying mess to maintain. Sorry, but I'm not going to provide instructions for something that seems very clearly a bad idea.