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

Security issue #5

Closed
renkun-ken opened this issue May 29, 2020 · 11 comments
Closed

Security issue #5

renkun-ken opened this issue May 29, 2020 · 11 comments

Comments

@renkun-ken
Copy link
Contributor

@renkun-ken renkun-ken commented May 29, 2020

The http server works nicely with demand that requires an external viewer to view the graphics outside R. If the user is using a personal computer and httpgd http server is started from localhost, there's no security issue on this. However, if the http server is started in a server with many users, there might be some demand that the graphics should be private to the user that creates the graphics, i.e. not visible to other users.

Currently, any user on the same server could visit the localhost:port (if port is known by others) and see the graphics.

I'm wondering if something could be done so that there's a way to prevent other users from seeing the graphics. One way that comes to my mind is that user could supply or httpgd to generate a token before starting the http server. Only user with this token specified somewhere (e.g URL query params) could visit the graphics.

@nx10
Copy link
Owner

@nx10 nx10 commented May 29, 2020

A security token can now be set on startup with httpgd(token="secret").

@HenrikBengtsson
Copy link

@HenrikBengtsson HenrikBengtsson commented May 29, 2020

Just stumbled upon this issue. Thxs for the quick fix. For those who wonder how this will work, you'll just have to add that secret token to the viewing URL, e.g.

> httpgd::httpgd(token="secret")
httpgd live server running at:
  http://127.0.0.1:8288/live?token=secret

@renkun-ken
Copy link
Contributor Author

@renkun-ken renkun-ken commented May 29, 2020

I'm also wondering if there's a function to return the URL so that it is easier to program with? e.g. calling utils::browseURL().

@nx10
Copy link
Owner

@nx10 nx10 commented May 30, 2020

You can now call httpgdURL() from R after a server is startet which returns the address as a string and httpgdState() which returns an R list object with all parts of the URL.

@nx10 nx10 closed this as completed May 30, 2020
@nx10 nx10 reopened this May 30, 2020
@nx10
Copy link
Owner

@nx10 nx10 commented May 30, 2020

Should randomly generated tokens be used by default when no token is specified? Currently tokens are deactivated by default.

@renkun-ken
Copy link
Contributor Author

@renkun-ken renkun-ken commented May 30, 2020

I guess we could make token accept the following values:

  • NULL or FALSE to indicate there's no token
  • a string to indicate there's a user supplied token
  • TRUE to indicate a randomly generated token

Since shiny apps have similar issue, it is okay for me that no token is the default unless user explicitly want this.

@r2evans
Copy link

@r2evans r2evans commented Jun 1, 2020

Perhaps it's just the paranoid in me, but on a similar note would it help to randomize the port=? Minor, but since you're already discussion tokens and the ability to print the URL on the console (and perhaps auto-browse it with utils::browseURL), is having a default port of 8288 meaningful?

@renkun-ken's point about multi-user systems drive home this point. Since it's printing the URL on the command-line when I start it anyway, I don't see any reason not to both randomize the port number and default to applying a (random) token. This makes it about as resilient to snooping as you can get at this point. (It does require a little resiliency in finding that port number and shifting if in use.)

I vote that you start more-secure and allow the user to opt for less security.

@nx10
Copy link
Owner

@nx10 nx10 commented Jun 1, 2020

token is now by default set to TRUE to generate a random 8 character alphanumeric token. If it is set to a number, a random token of that length will be generated. FALSE deactivates the security token.
I removed 8288 as the default port. If no port is specified, the OS will assign a free port.

Edit: @r2evans is right, it should be secure by default.

I am not sure if we should not use a default port the user can remember. What are your opinions?

@r2evans
Copy link

@r2evans r2evans commented Jun 1, 2020

My vote (not that it's a secret):

In the general single-user environment, if you make general use "easy" (either copy/paste the URL from the console or more easily incorporate utils::browseURL), then making it secure by default will likely introduce little if any inconvenience: the habit will be to copy/paste the URL as-is or allow it to open a browser page (hands-off). If the preference is to always use the same port/token, then they can override the defaults.

In a multi-user environment, it is as secure as it can be by default (port+token) short of SSL and certificates, make them choose insecure with arguments.

For ornery users who would really prefer to not type in ports and/or tokens each time, you might consider adding options, where the defaults are sane (allowing them to set personal prefs in ~/.Rprofile):

httpgd <-
  function(host = getOption("httpgd.host", "127.0.0.1"),
           port = getOption("httpgd.port", 0L),
           width = 720,
           height = 576,
           bg = "white",
           pointsize = 12,
           system_fonts = list(),
           user_fonts = list(),
           recording = TRUE,
           cors = FALSE,
           token = getOption("httpgd.token", TRUE)) {

In related packages, I've found it useful when the "random port" remains constant for the current R session. It's not hard to do: generate a random port and token in .onLoad and/or you can use a local({ ... function(...) {... } }) trick for a function (likely httpgd::httpgd).

(I apologize for the spiral features here, but I suggest that security should be a compromise for the user, but you don't have to make it super difficult. Or perhaps you should :-) *shrug*)

@renkun-ken
Copy link
Contributor Author

@renkun-ken renkun-ken commented Jun 2, 2020

@nx10 Definitely happy to see the design of using free port and token by default.

@nx10
Copy link
Owner

@nx10 nx10 commented Jun 2, 2020

I think the discussion has moved on a bit from the original issue (which was addressed with security tokens and randomized ports), so I moved it to a new issue and will close this for now.
If you think otherwise just let me know.

@nx10 nx10 closed this as completed Jun 2, 2020
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

No branches or pull requests

4 participants