Hello guys,
I need to enhance security for my Jupyter deployment and prevents users from doing some commands.
I’ve already disabled the terminal notebook (c.ServerApp.terminals_enabled = False) and others feature such as output/notebook download.
I’m trying to disables some features that can cause securities issues such as:
- Disable magic commands (e.g., “!env”, “!ls”…)
- Disable Shell commands (e.g., “%%bash”…)
- Block package installation (should be done by blocking “!pip”)
- Restrict access to system modules on the IPython Kernel (“os”, “sys”, “subprocess”, “socket”,“pathlib”, “pwd”…)
I’m using the latest Zero to JupyterHub (Z2JH) on Kubernetes with the IPython Kernel.
I’ve add some configuration in my “jupyter_notebook_config.py” but I couldn’t find any configuration related to shell and magic commands.
I’ve managed to block the import of system package with a python script, but it was system wide, and when disabling sys and os, the notebook did no longer launched, and couldn’t make in works in the Kernel configuration only.
Is there any configuration out there that would at least be able to disabled magic and shell commands?
Security is achieved through defense-in-depth, and the perimeter set up by python itself (much less IPython, much less IPython-on-a-websocket) is very porous indeed. In such a case, one must consider what value will actually be left for a regular user after all the protections are in place, and whether this has gone far enough to keep an actual bad actor from doing something: blue has to be perfect all the time, red just has to get lucky. Ultimately, is allowing any user to run any arbitrary code in any form suitable for the desired protection?
A potential alternative is to move the compute to the browser with e.g. jupyterlite, and restrict access in a more traditional way, via well-typed REST/GraphQL/whatever API calls with predictable/validate-able inputs and outputs which can inherit standard web security best practices.
1 Like
Hello,
thank you for your response, the things is, on a python or system level, we can’t have a high security level because it will break the notebooks. In the kernels you can manage what will be use or enabled for the users, which is what we wants on jupyter. It’s not about having a 100% secured notebook, but making it more difficult, if not impossible, to do malicious things on them, even if it’s running on a Kubernetes pods.
For those with similar problem, I have for now created a custom class from IPythonKernel (ipykernel/ipykernel/ipkernel.py at 188f39c509f1056c3784aad6954498f31de955a3 · ipython/ipykernel · GitHub). The kernel is launching with my custom class IPKernelApp.launch_instance(kernel_class=SecureKernel) instead of the standard launch_instance.
In my custom class I’ve removed the “!” usage and filter the use of “%” and “%%” commands with a whitelist, remove the commands in the cell/line, returns an error message if it’s not allowed to use and execute the rest of the code using the do_execute from IPythonKernel.
The import and dynamic import on some specific modules are also disabled the same way. I haven’t found a more elegant solution yet.
If you’re running on kubernetes, I would highly recommend exploring something like https://tetragon.io/ or KubeArmor | KubeArmor instead for your purposes. For example, here’s a KubeArmor policy that will block all ‘bash’ calls: Policy Examples for Containers | KubeArmor (first one). That page also has examples of only allowing access to certain files, or even only allowing specific processes to run (like python
). I think this will not only provide better security, but also be easier to maintain for you in the long run than maintaining custom IPython kernels.
1 Like
This sounds contradictory?
Anyways, I would bet an arm and a leg that whatever solution you devise on ipykernel
level can escaped in less than a few hours. It just does not come with any guarantees for this use case.
feature such as output/notebook download
Unless you also control the browser (e.g. a secure environment), it is easy to workaround. Also, creates an incentive for users to take pictures with their phones which is even less secure (this is the regular problem of locked down systems in research and health…).
What I meant, is that you nothing can be 100% secure. The point is to disable some shell / magic / packages from being used to prevent users to be able to break anything or extract information. The risk is already low, as the Kubernetes cluster is already secured and the notebook are launched on pods using users with restricted rights.