Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added secure_write to function for cookie / token saves #77

Merged
merged 8 commits into from
Aug 28, 2019

Conversation

MSeal
Copy link
Contributor

@MSeal MSeal commented Aug 19, 2019

This follows an advisory suggesting this change be made to help protect the secret files from being exposed to other users on a box running jupyter.

@MSeal
Copy link
Contributor Author

MSeal commented Aug 19, 2019

Like a patch release should closely follow the merge.

@MSeal
Copy link
Contributor Author

MSeal commented Aug 19, 2019

@minrk @SylvainCorlay @Carreau @jasongrout I can't add reviewers to this PR directly it seems, so here's your ping :)

@jasongrout
Copy link
Contributor

Also ping @Zsailer

@MSeal
Copy link
Contributor Author

MSeal commented Aug 19, 2019

jupyter/jupyter_client#469 has the same change for the client. It was suggested we move this to core after we get both places patched.

@MSeal
Copy link
Contributor Author

MSeal commented Aug 19, 2019

One thing to note is that for Windows you can't set the group permissions with chmod (see failing appveyor test on the server PR) :/

It might require something like https://stackoverflow.com/questions/12168110/setting-folder-permissions-in-windows-using-python to get passing. Thoughts?

@rolweber
Copy link
Contributor

Sounds reasonable. Are there other Jupyter projects that already depend on pywin32? We need to make sure that the dependency only applies on Windows.

Do you have a pointer to the advisory that asks for this change?

@MSeal
Copy link
Contributor Author

MSeal commented Aug 20, 2019

@rolweber I added you to the relevant thread.

@rolweber
Copy link
Contributor

rolweber commented Aug 26, 2019

Travis tests failed:

  File "/home/travis/build/jupyter/jupyter_server/jupyter_server/serverapp.py", line 685, in _default_cookie_secret
    self._write_cookie_secret_file(key)
  File "/home/travis/build/jupyter/jupyter_server/jupyter_server/serverapp.py", line 694, in _write_cookie_secret_file
    with secure_write(self.cookie_secret_file, True) as f:
  File "/opt/python/3.7.1/lib/python3.7/contextlib.py", line 239, in helper
    return _GeneratorContextManager(func, args, kwds)
  File "/opt/python/3.7.1/lib/python3.7/contextlib.py", line 82, in __init__
    self.gen = func(*args, **kwds)
TypeError: secure_write() takes 1 positional argument but 2 were given

The second argument , True is not recognized.

@MSeal
Copy link
Contributor Author

MSeal commented Aug 26, 2019

Gah copy paste issue from jupyer_client change -- forgot the mode option

@rolweber
Copy link
Contributor

The logic currently is:

  1. Create the file (open+close)
  2. Check the file permissions
  3. Open the file again

That means the file which gets opened in 3 is not necessarily the file that was checked in 2.
A safer sequence would be:

  1. Create and open the file
  2. Check the file permissions (while the file remains open)
    The check with stat should be possible while the file is open.

And could you please add a newline at the end of test_utils.py?

@rolweber
Copy link
Contributor

rolweber commented Aug 26, 2019

Are there other flags that can reasonably be set when opening the file, such as requesting exclusive access?
On second thought, that is pointless. If the file permissions are restricted as expected, then only the user could open the file in parallel.

I'm wondering if renaming of the open file could lead to checking the wrong file. But even then, the solution would be safer than not doing anything at all.

@MSeal
Copy link
Contributor Author

MSeal commented Aug 26, 2019

So on some systems I've run into runtime issues editing permissions while a file is open will result in failure (looking at you windows 7). In testing I also found the open command was not changing file permissions for existing files, which is why I did the remove first. Because of these problems I opted for a two-pass solution. Since this is only a write and not a read command and the write is a truncate operation I believe this is safe. A user would need admin or user permissions to move the file being touched. So they already have escalated permissions to simply read/write the affected file anytime after the secure_write completes. Anything in the file ahead of time is removed with the truncate on write command, so injection shouldn't be possible as well.

Do you think there is still something open I'm not thinking about?

@rolweber
Copy link
Contributor

rolweber commented Aug 27, 2019

If it's Windows that requires special treatment, I'm very much in favor of treating that case in the if os.name == 'nt': branch of the code. You could do the close-modify-reopen sequence there. The second call to open shouldn't have the O_CREAT flag set, because there you expect to open an existing file.

Removing the file and creating a new one makes sense. I'm not sure if permissions could be set on some systems that would prevent the user from removing the file, while still allowing writes to it. But you're right, we shouldn't overthink this. Whoever messes with file permissions or renaming during the secure_write sequence will have enough rights to mess with the file after creation as well.

Still, could you please refactor the logic so that the file is created and opened only once for the non-Windows case?

@MSeal
Copy link
Contributor Author

MSeal commented Aug 27, 2019

Yep I will make the change tomorrow then.

Copy link
Contributor

@rolweber rolweber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@rolweber
Copy link
Contributor

Thanks!

@rolweber rolweber merged commit 9153ecf into jupyter-server:master Aug 28, 2019
@MSeal
Copy link
Contributor Author

MSeal commented Sep 13, 2019

@rolweber @SylvainCorlay could we get a patch release with these changes? Since there some security concern driving this change it'd be good to not have the issue visible with no patch available for users.

@rolweber
Copy link
Contributor

I'm not in a position to make releases, but I agree that this change merits one.

Zsailer pushed a commit to Zsailer/jupyter_server that referenced this pull request Nov 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants