jupyter
jupyter copied to clipboard
Download/Upload Permission per User
Dear Guys,
I have concern about security on jupyter itself. Can we disable 'Download' or 'Upload' feature per user? For example, i need to prohibit an 'user' for Downloading some file or Uploading. It would be great if we have config on this. Thanks.
Best regards
Preventing upload might be feasible, but who are you trying to protect from what? Jupyter is a tool to let users do things, and for anything you want to prohibit, there's probably a way to get round it.
If you don't trust your users, the usual strategy is to give them notebook servers running in individual docker containers or similar, so they can't affect anything outside their container. JupyterHub can help with this.
What is the ultimate goal of preventing upload / download? Users can create files with code execution, so preventing upload doesn't prevent users from creating files with arbitrary contents.
Further, the upload mechanism is how notebooks are saved, so preventing upload would likely also mean preventing the saving of changed notebooks. The same goes for download, really. Notebooks have to be retrieved in order to view them.
I'm also looking for this functionality. It doesn't provide security to disable, but it sends a signal to the user that they shouldn't use it in that way.
I'm in a corporate shared infrastructure environment, so want to avoid users uploading massive files where possible.
Also interested in this functionality. In our case, we are hoping to provide a sandboxed environment to allow researchers to conduct analysis of large data sets that the notebook environment would have access to, but would like to block them from taking the raw data out via the file explorer/download button.
Is there any way to solve this case? I alse want to block them from taking the important data out.
I had a similar need to disable download of files from the home folder. What I did was host the jupyter server behind nginx. Then on nginx, I proxy-pass'ed all requests to port 80, to 127.0.0.1:8888, but anything that began with /files was sent to a black hole. This is a simple mechanism to enable students/researchers to be able to use the csv files of any large dataset using the jupyter notebook, but prevent them from downloading.
@sulicny Did you ever find a solution to this problem?
@prkamath Hello, can you share your nginx configuration to achieve this ?
@prkamath Hello, Can you share your nginx config?
@sundh4 Did you find a solution to this one? I don't see any solution to disable upload and download options on Google either. I am new to the Jupyter world. I tried to modify the code to see if the Download option can be removed. Though I change the pieces of code to the download options, when I re-build and run Jupyterlab, it doesn't work. Is it not the code for Jupyterlab that we are supposed to change? Did anyone find a solution to this?
I am using JupyterHub and trying to figure this out also. I need to disable downloads even if just means to get rid of the button in the UI. Any ideas on this yet?
I tried this in my kubernetes cluster I am using jupyterhub (installed via helm) which launches jupyternotebooks, I set in my ingress "/files" route to redirect to default-http-backend which is just an nginx image container (black-hole) but sadly it still initiate download.
I had a similar need to disable download of files from the home folder. What I did was host the jupyter server behind nginx. Then on nginx, I proxy-pass'ed all requests to port 80, to 127.0.0.1:8888, but anything that began with /files was sent to a black hole. This is a simple mechanism to enable students/researchers to be able to use the csv files of any large dataset using the jupyter notebook, but prevent them from downloading.
Has anyone tried this in Jupyterhub? (installed in k8 using helm)? In JHub documetation, there is no config to override the ingress path.
I did what prkamath suggested on my kubernetes cluster with an ingress like this :
spec:
rules:
- host: mynotebook.domain.com
http:
paths:
- backend:
serviceName: ingress-85cc0a1244a20d92542554a4c81ed873
servicePort: 8888
- backend:
serviceName: ingress-c7ae2a46556ba756ee908912db5735e1
servicePort: 9999
path: /files
As port 9999 doesn't exist, users get a nice "502 Bad Gateway" when they try to download something.
I did what prkamath suggested on my kubernetes cluster with an ingress like this :
spec: rules: - host: mynotebook.domain.com http: paths: - backend: serviceName: ingress-85cc0a1244a20d92542554a4c81ed873 servicePort: 8888 - backend: serviceName: ingress-c7ae2a46556ba756ee908912db5735e1 servicePort: 9999 path: /files
As port 9999 doesn't exist, users get a nice "502 Bad Gateway" when they try to download something.
I tried the. "/files" but still initiate the download. Then I discovered that in jupyterhub when the notebook is spawned, the URL for the notebook for each user is: http://domain/user/username/
I tried this approach.. I am returning 403 if the path is "/user/username/files/xxx" it does show 403 page when you type the same url download in the browser but when clicking the download button, it still initiate the download of files. :(
I use the docker image jupyter/datascience-notebook behind a nginx and each user has it own docker image, so I don't have /user/username =/
Adapting this blog post to my setup did the trick for me.
Adapting this blog post to my setup did the trick for me.
I just created my own docker image adapting from the blog post and used it in my hub single user image. It works! thank you so much @ePerspi
Adapting this blog post to my setup did the trick for me.
I just created my own docker image adapting from the blog post and used it in my hub single user image. It works! thank you so much @ePerspi
Can I ask how you did this exactly? I am trying to add a manual config in a user-defined image, but I am not able to get the 304 error...
Adapting this blog post to my setup did the trick for me.
I just created my own docker image adapting from the blog post and used it in my hub single user image. It works! thank you so much @ePerspi
Can I ask how you did this exactly? I am trying to add a manual config in a user-defined image, but I am not able to get the 304 error...
I am sending them to a blackhole (non-existing endpoint), thus the error that would show to the users is "404". Since my goal is just to stop them from downloading the files..
Adapting this blog post to my setup did the trick for me.
I just created my own docker image adapting from the blog post and used it in my hub single user image. It works! thank you so much @ePerspi
Can I ask how you did this exactly? I am trying to add a manual config in a user-defined image, but I am not able to get the 304 error...
I am sending them to a blackhole (non-existing endpoint), thus the error that would show to the users is "404". Since my goal is just to stop them from downloading the files..
I see, I am also curious how you adapted the solution in the blog post to your own docker image. Could you share that with us also? Greatly appreciated!!
With the help of @prkamath's answer and settings shown in Nginx + notebook issue, we found this Nginx setting worked for us. Thanks!
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
server_name 0.0.0.0;
# set client body size to 20M #
client_max_body_size 20M;
# To open jupyter notebook
location / {
# Set YOUR jupyter service IP and port
proxy_pass https://***.***.***.***:port;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Forbid downloading from jupyter
location /files {
return 444;
}
# location /notebooks {
# return 444;
# }
# # Cannot edit text files, such as *.py, if set
# location /edit {
# return 444;
# }
access_log /data/logs/nginx/8000.log;
}
https://github.com/Shrikantgrh/JupyterLab-DownloadUploadDisabled
Adapting this blog post to my setup did the trick for me.
I just created my own docker image adapting from the blog post and used it in my hub single user image. It works! thank you so much @ePerspi
Can you detail on how you were able to achieve this? The blog post entails creation of a lifecycleHook for adding configuration - any ideas how to achieve that via Jupyterhub on k8s?
Hey there, I'm going through old issues and it seems to me that it makes sense to close this one.
Thanks everyone and happy hacking! :bowtie: