Anyone who can use a Jupyter server can run arbitrary code as the account that started it. So treat reaching the server as equal to a shell login: keep authentication on, put it behind TLS and a network boundary, limit who is authorized, and never run it as a highly privileged user.
Start from the vendor guidance
The Jupyter Server documentation states that access means running arbitrary code and recommends strict access controls. Token authentication is on by default: the server logs a generated token at startup, and after you visit a tokenized URL a browser cookie keeps you logged in. You can set a password with the jupyter server password command, which stores a hashed password in your config file and disables default token authentication. Disabling both is marked NOT RECOMMENDED unless another layer handles access restrictions.
The checklist
- Authentication on. Keep tokens or a password. Do not run with both disabled just to make a demo easier.
- Bind carefully. Listening on all interfaces exposes the port to everything that can route to it. Bind to localhost and use an SSH tunnel or an authenticating reverse proxy.
- TLS. The Jupyter page above does not cover TLS, so use its other documentation or terminate TLS at a proxy you control.
- Authorization. The documentation says that by default all authenticated users have full access. If several people share a server, add an authorizer or give each person their own instance.
- Least privilege host account. Run the server as a normal user with only the access the work needs, not root, and not an account that holds production cloud credentials.
- Kernel transport. The transport_encryption setting can enable CurveZMQ encryption for kernel sockets, with values disabled, auto or required. Consider it where kernels run on separate hosts.
- Credentials on the box. Look at the environment and home directory for cloud keys and warehouse passwords. A compromised server hands them over.
- Updates. Keep the server and extensions current, and review extensions you install.
Notebook trust
The documentation explains that notebook outputs are trusted only if the notebook's signature matches an entry in your signatures database. Untrusted HTML and JavaScript are sanitized and never executed. You can trust a notebook by re-running it, using jupyter trust, or choosing File and Trust Notebook. Do not trust notebooks from strangers just to see their charts.
Finding forgotten servers
Teams start servers for a project and forget them. Scan your cloud accounts and internal ranges for the default port, list running servers with the jupyter server list command on hosts you manage, and shut down what has no owner.
Detection
Log access to the proxy in front of the server and alert on logins from unexpected networks. Log process creation on the host if you can, since code execution is the expected abuse.
Where Safeguard fits
Safeguard's asset discovery helps you find what exists in your estate, and its dependency scanning checks the packages a notebook environment installs. Try the free scan at https://gold.safeguard.sh/scan.
Quick check
Is a Jupyter server without authentication acceptable behind a firewall?
Only if another layer reliably restricts access. The documentation marks disabling both token and password as not recommended otherwise.
Do all authenticated users have limited rights by default?
No. By default all authenticated users have full access, so add an authorizer or separate instances.
Sources
Last reviewed: 19 October 2026.