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

Launch the browser with a redirect file #4260

Merged
merged 4 commits into from
Dec 13, 2018

Conversation

takluyver
Copy link
Member

This avoids putting the authentication token into a command-line argument to launch the browser, where it's visible to other users. Filesystem permissions should ensure that only the user who started the notebook can use this route to authenticate. Thanks to Dr Owain Kenway for suggesting this technique.

We should decide whether the "Copy/paste this URL into your browser" message should show the real URL (as it currently does), the file:// URL, or both. You may need the real URL to use the notebook via SSH tunnelling, or when the notebook server is running in a container, but it makes it easy to inadvertantly reveal your token on a multi-user system by running a command that contains it.

If we go for this approach, we can also remove the single-use token, but I haven't done that yet.

This avoids putting the authentication token into a command-line
argument to launch the browser, where it's visible to other users.
Filesystem permissions should ensure that only the user who started the
notebook can use this route to authenticate.
Thanks to Dr Owain Kenway for suggesting this technique.
@takluyver takluyver added this to the 5.7.3 milestone Dec 11, 2018
@minrk
Copy link
Member

minrk commented Dec 11, 2018

Thanks for the PR! I've tested this locally (on mac) and it works great.

I'm not sure what to do about the long-term token. Some thoughts:

  1. on certain shared-user systems (mostly linux), clicking the link could result in a process with the token on the command-line, which can be snooped by other users on the system (well-known issue on shared machines)
  2. this file approach would work great locally, but it would be super inconvenient for containers/remote servers
  3. this is only an issue when the user's browser is on a shared system (i.e. it doesn't matter if the remote machine where the server actually is is shared)

One option is to use this file approach with the long-term token (~useless for the container/remote case). Another option is to not make the URL copy/pasteable, only the url and token separately. Then users cannot open the link by clicking it, they must open the not authenticated url and then paste the token into the login form. We've basically had this in certain cases on and off. One thing's for certain, though: if we make the URL not clickable/pasteable, even for security reasons, folks are going to be annoyed at the resulting inconvenience, as we have seen in #3605 and friends. Yet another option is to put a disclaimer next to the link, saying that it should be copied/pasted, not click-to-open. Maybe the last one is best. What do you think?

@takluyver
Copy link
Member Author

I've also tested it locally on Linux. It would be good for someone to check on Windows, but so long as pathname2url from the standard library does its job correctly, it should work there too.

For presentation in the terminal, how about something like:

To access the notebook, open this file in a browser:
    file:///path/to/file.html
Or copy and paste one of these URLs:
    http://localhost:8888/?token=faec...
    http://127.0.0.1:8888/?token=faec...

If other users are logged in to this computer, don't click the http URLs in the terminal
  More info: http://jupyter.something

I'm 50/50 on the message at the end. On the one hand, it seems fair to let the security conscious know that this might matter. But many users aren't going to read it anyway, and for most of those who would, it doesn't matter, so it's just an extra thing to think about and worry about.

@owainkenwayucl
Copy link

owainkenwayucl commented Dec 11, 2018

I think maybe one option for the permanenent token is to print the token (not the URL for it) for copy/pasting and give a URL for a file that redirects to that token as a link?

I mean, at least as default behavior - showing the raw URL could be an option that's turned on?

@minrk
Copy link
Member

minrk commented Dec 12, 2018

@takluyver I tested on Windows 10 + Python 3.7 and it worked great.

@takluyver
Copy link
Member Author

I'll probably merge this tomorrow and make a release soon after, unless you want to do or check anything more.

@minrk
Copy link
Member

minrk commented Dec 13, 2018

Works for me. Thanks @owainkenwayucl for the idea!

@minrk minrk merged commit 51dae23 into jupyter:master Dec 13, 2018
@takluyver
Copy link
Member Author

BTW @owainkenwayucl, are you happy to be credited in the release announcement for the new version?

@takluyver takluyver deleted the browser-open-file branch December 13, 2018 10:16
@takluyver
Copy link
Member Author

@meeseeksdev backport to 5.7.x

meeseeksmachine pushed a commit to meeseeksmachine/notebook that referenced this pull request Dec 13, 2018
takluyver added a commit that referenced this pull request Dec 13, 2018
…0-on-5.7.x

Backport PR #4260 on branch 5.7.x (Launch the browser with a redirect file)
@owainkenwayucl
Copy link

I'm happy to be credited (if it's not too late).

I just update to 5.7.4 and I have the fix and it looks good!

@takluyver
Copy link
Member Author

Great! I assumed that you wouldn't mind, so your name is in the announcement email and the release notes.

@dhumbird
Copy link

This breaks a use case where I'm calling jupyter from WSL but opening the browser in Windows (for graphics reasons). The Windows browser can't see the local file in the WSL filesystem. URL copy/paste still works. Anyway to override this--or let me choose a different location for the local file?

@takluyver
Copy link
Member Author

You can override where it saves the file by setting the JUPYTER_RUNTIME_DIR environment variable. But it will always construct the file:// URL assuming that the browser can access the same path that the server sees, so it only works for local connections.

I've no idea how WSL works, but you might be able to script launching Jupyter, getting the http:// URL and launching a browser with that.

@jpweytjens
Copy link

WSL stores all Linux related files in C:\Users\%USERNAME%\AppData\Local\Packages. Microsoft strongly discourages you to edit these files in any way from the host operating system being Windows. Even if you change the JUPYTER_RUNTIME_DIR to a location on the Windows side, the path will still be formatted in Unix style. As such, a browser running in Windows won't understand the path. Microsoft does offer the wslpath tool to convert paths from Unix to Windows style and vice versa.

It is not immediately clear to me how I should script launching Jupyter. How would you recommend to go about this?

@dhumbird
Copy link

In fact I was using a script to make it work in the first place---wslview from wslu. For now, I wrote the script below to use instead. Export this script as BROWSER environment variable in wsl and it will catch the filename, pull out the URL, and open the default Windows browser.

#!/usr/bin/perl
$file = $ARGV[0];
$file =~ s/file:\/\///;
$link = `grep href $file`;
($link) = $link =~ m/"(.*?)"/ ;
exec("powershell.exe Start $link");

@slel
Copy link

slel commented Jan 11, 2019

This introduced a bug reported and diagnosed at #4303. See #4340 for a fix.

@raulf2012
Copy link

Hello everybody,

I recently opened an issue related to this PR and it breaking my Jupyter lab workflow on WSL for windows

Ideally I would hope that there by an option (jupyter_config.py file?) that toggles the default behavior between the old "URL link" and new "redirect file" systems discussed here

Is this currently possible in any way?

I haven't tried dhumbird's work around, but it's a little clumsier than I'd prefer

Any thoughts?

Raul

@betteridiot
Copy link
Contributor

^ This has potentially cripples 50% of my students' build environments because they are WSL users. For those that got an Xserver working properly, firefox/chrome (from within Linux) can spawn from file.

However, for those that cannot get Xserver working and set the BROWSER variable to a Windows firefox.exe/chrome.exe this completely breaks their build.

The workaround right now is to downgrade notebook to version 5.7.0

@SamuelMarks
Copy link

It's May now, any chance we can get a configuration option to open the old URL link by default, rather than the file:// one?

Note: file:// fails to render any JavaScript on Firefox Developer Edition. Others have experienced this issue: #4598

PS: I've overriden c.NotebookApp.browser to Chrome, in the meantime.

@betatim
Copy link
Member

betatim commented May 24, 2019

On Firefox the page resulting from the redirect doesn't quite work.

Is there a reason to use the meta -refresh instead of doing it with JS? If not, I'd open a PR that uses JS to do the redirect and falls back to the meta-refresh if JS isn't available. Does that sound like a good solution @takluyver @minrk?

@dhumbird
Copy link

Since this is still open, I should note that even the old method of Linux Chrome+Xserver doesn't work in WSL anymore. After I reinstalled WSL this month, I found that Chrome can now only be started with sudo and --no-sandbox. Firefox can still be started normally, but it sounds like that has other issues.
#4346
https://github.com/Microsoft/WSL/issues/3749

@minrk
Copy link
Member

minrk commented May 24, 2019

I think adding the js (and leaving meta-refresh, not removing it) should be fine. WSL seems to be a pretty big mess. Restoring the insecure behavior behind a flag is perhaps the best we can do. I don't love the idea, but WSL is unlikely to be used a lot on shared machines, I guess (or hope, at least), and it's only an issue for shared machines.

@roachsinai
Copy link

Thanks for it! Just curious about how other users on Linux get my token, if I use token as argument to open web browser.

Is there a link to explain it?

@owainkenwayucl
Copy link

@roachsinai: If they run ps axu they can see all the processes running on the system and the command used to launch them. If you launch with the token in the url passed to the browser they can then see the token.

Obviously this is not as much of an issue on a single user machine (although I guess in theory a malicious piece of software could use it to become other users) but on a multl-user machine it is a problem.

In particular in my testing it was possible to successfully race the user's browser launch to authenticate before them by using a browser that was already open. Because Jupyter falls back to cookies for authentication (it has to), if the legitimate user had opened the notebook server before, they'd never even know that someone else was connected to their session.

@roachsinai
Copy link

@owainkenwayucl Thanks you so much for this explanation!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet