Skip to content

Authentication Cookies Remain Valid After Password Reset and Server Restart #1566

@emin63

Description

@emin63

Authentication Cookies Remain Valid After Password Reset and Server Restart. For example, if an employee leaves an organization using jupyter-server and the organization changes the password and restarts the server, the employee can still access the server (if the employee has a browser with the old stored cookie).

Description

A persistent cookie secret vulnerability allows authenticated users to maintain indefinite access even after password changes. The cookie secret used to sign authentication cookies is stored in a permanent file (~/.local/share/jupyter/runtime/jupyter_cookie_secret) that is never automatically rotated or cleared, allowing stolen or compromised cookies to remain valid indefinitely regardless of password resets.

To actually revoke the cookie, you must delete the permanent file (usually at ~/.local/share/jupyter/runtime/jupyter_cookie_secret) and restart the server.

The vulnerability exists in the _default_cookie_secret() method in jupyter_server/serverapp.py (
https://github.com/jupyter-server/jupyter_server/blob/main/jupyter_server/serverapp.py).

Possible Fixes:

  1. Store a generation value in the user cookie which is the mod time of the cookie secret file. Have the server store this generation value when it reads (or otherwise creates the cookie secret). When decoding the cookie in (https://github.com/jupyter-server/jupyter_server/blob/main/jupyter_server/auth/identity.py), check that the cookie generation is greater than or equal to the server secret generation.
  2. Alternatively, use something like the refresh-token/access-token structure for JWTs.

See also some related discussion in jupyter/notebook#3842.

Reproduce

  1. Set a password:
    • jupyter server password # Set password to "password1"
  2. Start the server:
    • jupyter server
  3. Log in with the password and capture the authentication cookie (e.g., just login with a browser).
  4. Change the password:
    • jupyter server password # Change password to "password2"
  5. Restart the server.
  6. Login again using the previously stored cookie (e.g., just login again with the browser you logged in with the first time).

Expected behavior

Ideally changing the password should prevent someone who does not know the new password from gaining access to the server. At a minimum, changing the password and restarting the server should prevent someone who does not know the new password from gaining access.

Context

  • Operating System and version: Ubuntu 24
  • Browser and version: Any
  • Jupyter Server version: Any
Troubleshoot Output (Unrelated packages omitted)
        jupyter                   1.1.1
        jupyter_client            8.6.3
        jupyter-console           6.6.3
        jupyter_core              5.9.1
        jupyter-events            0.12.0
        jupyter-lsp               2.3.0
        jupyter_server            2.17.0
        jupyter-server-mathjax    0.2.6
        jupyter_server_terminals  0.5.3
        jupyterlab                4.4.9
        jupyterlab_pygments       0.3.0
        jupyterlab_server         2.27.3
        jupyterlab_widgets        3.0.15
        tornado                   6.5.2
Command Line Output
$ jupyter lab
[W 2025-10-29 14:03:36.531 ServerApp] ServerApp.token config is deprecated in 2.0. Use IdentityProvider.token.
[W 2025-10-29 14:03:36.531 ServerApp] ServerApp.password_required config is deprecated in 2.0. Use PasswordIdentityProvider.password_required.
[I 2025-10-29 14:03:36.605 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2025-10-29 14:03:36.609 ServerApp] jupyter_server_mathjax | extension was successfully linked.
[I 2025-10-29 14:03:36.613 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2025-10-29 14:03:36.617 ServerApp] jupyterlab | extension was successfully linked.
[I 2025-10-29 14:03:36.617 ServerApp] nbdime | extension was successfully linked.
[I 2025-10-29 14:03:36.621 ServerApp] notebook | extension was successfully linked.
[I 2025-10-29 14:03:36.926 ServerApp] notebook_shim | extension was successfully linked.
[I 2025-10-29 14:03:36.951 ServerApp] notebook_shim | extension was successfully loaded.
[I 2025-10-29 14:03:36.953 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2025-10-29 14:03:36.954 ServerApp] jupyter_server_mathjax | extension was successfully loaded.
[I 2025-10-29 14:03:36.955 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[I 2025-10-29 14:03:36.962 LabApp] JupyterLab extension loaded from venv/lib/python3.12/site-packages/jupyterlab
[I 2025-10-29 14:03:36.962 LabApp] JupyterLab application directory is venv/share/jupyter/lab
[I 2025-10-29 14:03:36.963 LabApp] Extension Manager is 'pypi'.
[I 2025-10-29 14:03:37.031 ServerApp] jupyterlab | extension was successfully loaded.
[I 2025-10-29 14:03:37.100 ServerApp] nbdime | extension was successfully loaded.
[I 2025-10-29 14:03:37.104 ServerApp] notebook | extension was successfully loaded.
[I 2025-10-29 14:03:37.104 ServerApp] Serving notebooks from local directory: 
[I 2025-10-29 14:03:37.104 ServerApp] Jupyter Server 2.17.0 is running at:
[I 2025-10-29 14:03:37.104 ServerApp] http://localhost:8888/lab
Browser Output N/A
Paste the output from your browser Javascript console here, if applicable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions