# Potential security issue?

**URL:** <https://discourse.jupyter.org/t/potential-security-issue/6756>\
**Category:** Security\
**Created:** [November 15, 2020, 2:36pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756 "2020-11-15T14:36:47Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![goose](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@goose](https://discourse.jupyter.org/u/goose)\
**Post date:** [November 15, 2020, 2:36pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/1 "2020-11-15T14:36:48Z")

</div>

I offer jupyter notebook instances to users.  
The instances are setup so that a random token is generated, and the user receive a url containing the token (eg. [http://35.12.23.24:8888/?token=fdeb28d49186887fd091e24092853b43](http://35.12.23.24:8888/?token=fdeb28d49186887fd091e24092853b43)).

This generates a cookie for the user, such that the url [http://35.12.23.24:8888](http://35.12.23.24:8888) does not require the token later on.

When the instance is destroyed, and a new one is created using the same IP address but on a different server, I am able to login with the existing cookie in my browser using the url without token, no token is requested. Removing the cookie disables access to the server.

I see no reason how this is happening, the instances are created from the same base image but are deployed on different servers. I confirmed that the token generation was different on every occasion.

The token is set in jupyter\_notebook\_config.py with  
“c.NotebookApp.token = ‘45711f4141c6630d1370e0b687f2ac93’”

---

<div class="post-metadata">

**Author:** ![jharris1993](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jharris1993/32/3037_2.png) [@jharris1993](https://discourse.jupyter.org/u/jharris1993)\
**Post date:** [November 15, 2020, 7:31pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/2 "2020-11-15T19:31:58Z")

</div>

Forgive me, I might be all wet, but here goes. . . .

Note that this is _ **not** _ based on my experience with Jupyter, (I have virtually none), but with my experience using client-server authenticated sessions.

This kind of process - in general - creates a token that binds a particular machine/browser/whatever with a particular server IP address. Jupyter appears to be doing the same thing, and doing it in the same general way.

It does this by generating a unique token, embedded into a persistent cookie, that is used to demonstrate if this particular user/browser has successfully authenticated here before.

In other words, I have machine “X”, and I go to your server at 35.12.23.24:8888. When I do this, the server system generates a unique token that associates _ **my machine** _ with _ **your server** _ located at 35.12.23.24. Even if that IP is a “front-end load balancer”, the association is between my specific machine and the server(s) located behind _ **that particular** _ IP address.

If I break that connection and then re-connect, I would expect that I would not need a new token because I have already been associated with that particular “server” (_i.e._ IP address) and the persistent cookie containing that token proves I’ve been there.

That’s what these things are supposed to do, and, (as far as I can tell), the behavior is exactly what I would expect to happen.

> [@](#):
>
> As a side note, what you describe here is _ **exactly why** _ this kind of _ **persistent** _ cookie/token can be a significant security hole if not managed properly.
> 
> Imagine what it would be like if you had a _persistent_ authentication token/cookie like this from your bank. The next person who opened that web site from your computer would have instant access to all your banking information!
> 
> In cases where a browser-based authentication cookie is needed, they’re typically given a very short lifetime, measured in minutes, so they expire quickly and cannot be re-used.

In your case it might not matter; but you should pay attention to this when using any kind of token/cookie based authentication method.

Perhaps you can explain what you want to be happening and why it needs to be happening that way?

A better description of what you want to accomplish and how you expect it to work, might help those who know more about this guide you.

Thanks!

---

<div class="post-metadata">

**Author:** ![goose](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@goose](https://discourse.jupyter.org/u/goose)\
**Post date:** [November 15, 2020, 9:52pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/3 "2020-11-15T21:52:45Z")

</div>

Hi,

Thanks for your reply.  
Our goal is to setup jupyter notebook servers automatically.  
The desired result is that when a different user receives a notebook server, we do not wish that previous users of a notebook server on that IP can get access.  
Eventually we would embed it in an IFrame.

For now it seems we can prevent our issue by using setting c.NotebookApp.cookie\_secret.

Would we be better off setting a random password instead? It seems the token remains valid also after setting a password.

---

<div class="post-metadata">

**Author:** ![jharris1993](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jharris1993/32/3037_2.png) [@jharris1993](https://discourse.jupyter.org/u/jharris1993)\
**Post date:** [November 16, 2020, 10:01am UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/4 "2020-11-16T10:01:49Z")

</div>

That is probably Jupyter-specific, which I claim zero expertise within.

Hopefully, someone who knows more about this in the Jupyter context can join in and help.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [November 16, 2020, 11:15am UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/5 "2020-11-16T11:15:27Z")

</div>

I regularly start/stop/recreate jupyter notebook instances, and have never seen the issue you describe. If I don’t provide the updated token I can’t access the notebook server. For example, if you run

```auto
docker run -it --rm -p 8888:8888 jupyter/base-notebook

```

multiple times you’ll always need to use the new token to connect to [http://localhost:8888](http://localhost:8888).

Could you please:

- tell us exactly how you’ve deployed your VMs
- show us your config file?

---

<div class="post-metadata">

**Author:** ![goose](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@goose](https://discourse.jupyter.org/u/goose)\
**Post date:** [November 16, 2020, 2:23pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/6 "2020-11-16T14:23:15Z")

</div>

Our config file looks like this:

```
c.NotebookApp.open_browser = False
c.NotebookApp.token = '615faf40a40465er0dbcf4e2b47190d2'
c.NotebookApp.custom_display_url = 'Jupyter Notebook'
c.NotebookApp.ip = '*'
c.NotebookApp.port = 8888
c.NotebookApp.allow_password_change = True
c.NotebookApp.quit_button = False

```

We copy an image which has an anaconda environment containing Jupyter Notebook and add these settings upon initialization. We generate the random token so we can build the url. (eg. [http://1.2.3.4:8888/?token=615faf40a40465er0dbcf4e2b47190d2](http://1.2.3.4:8888/?token=615faf40a40465er0dbcf4e2b47190d2))

We’ve now added

```
c.NotebookApp.cookie_secret

```

Set to a random value, which seems to fix our issue.  
The main difference I can think of is that we set the token vs letting Jupyter generate one.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [November 16, 2020, 2:55pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/7 "2020-11-16T14:55:25Z")

</div>

It sounds like you might’ve inadvertently baked a cookie secret into your image, which means it’s re-used instead of being regenerated:

> <https://github.com/jupyter/notebook/pull/1831>

This could potentially happen if you run jupyter-notebook at any point during the creation of the image. Did you create the image manually, is is it fully automated?

---

<div class="post-metadata">

**Author:** ![goose](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@goose](https://discourse.jupyter.org/u/goose)\
**Post date:** [November 16, 2020, 7:13pm UTC](https://discourse.jupyter.org/t/potential-security-issue/6756/8 "2020-11-16T19:13:27Z")

</div>

I think that’s probably exactly what happened, the image contains over 100 packages so during setup I ran several notebooks to test if all packages were present and working correctly.

Thanks for the info!
