la5nta / pat

A cross-platform Winlink client written in Go
https://getpat.io
MIT License
487 stars 87 forks source link

Web security overhaul: TLS and authentication by default #159

Open xylo04 opened 5 years ago

xylo04 commented 5 years ago

Branching from issue #132. The web APIs are currently wide open to anyone who can address the server. This is safe if the web service is restricted to serving to localhost, but if the service is exposed to the network (possibly including the internet), there is zero encryption or authentication to protect data like email messages or position reports in the outbox. (This discussion comes up because we'd like to add position report creation to the web GUI, which would create yet another sensitive API.)

I see this falling into two buckets: encryption with TLS, and authentication to the web frontend and API endpoints. Both buckets must be configurable to be enabled or disabled.

TLS encryption could possibly be tri-state:

However, I can't think of a use-case where optional is preferable to enabled or disabled, so that's probably a dumb idea.

Setting up TLS correctly could theoretically fix the broken "Powerful Features" (desktop notifications and geolocation) which browsers are starting to disable for "insecure origins."

Lacking encryption or authentication, we should recommend to users that they be very careful about configuring the scope of their http_addr.

DC7IA commented 5 years ago

I'm not sure adding these features will help make pat better at this point of time.

Instead I'd recommend installing apache2 and using .htaccess to make it accessible:

RewriteEngine On
RewriteRule (.*) http://localhost:8080/$1 [P]

This way you can access pat at https://yourdomain.tld/ on port 80/443.

Just enable https for apache and disable http to get encryption. :)

You can combine this with .htpasswd to restrict access to specific users.

I think this should be done later, there are many more issues I find more important right now, especially as you can get that feature relatively easy yourself.

DC7IA

harenber commented 5 years ago

Or, even easier, use traefik.io, which would even handle letsencrypt automatically (if you wanna use that) .

DL1THM

xylo04 commented 5 years ago

I like the Apache option; I'm not familiar with traefik.io, but if it works with Let's Encrypt, it also sounds like a good solution. Should the resolution to this issue be to document in the wiki the process of setting one of those up?

martinhpedersen commented 5 years ago

Yes, it would be nice to have a wiki page giving a brief overview on how to set up a reverse proxy with TLS enabled. The author has to take special care since it also needs to support websocket.

However, I'm afraid that it is not enough. How would you implement authentication? Keep in mind that the JS code does not support sending credentials to the API and/or when opening the websocket...

Maybe we need to implement native support for authentication? One idea, from me @ https://github.com/la5nta/pat/pull/146#discussion_r327029861:

Generate a token (print to terminal) to be used as an API authorization key. The token can be entered once in the web gui and stored as a cookie for future sessions from the same device.

blockmurder commented 5 years ago

Have you had a look at JWT? My knowlege about the endpoint services and the corresponding javascript/websocket parts are quite limited. After a couple of hours research this is what I came up with:

martinhpedersen commented 5 years ago

I put together a config file for nginx to enable TLS, for those that might be interested.

It requires commit 8c1a65b (will be included in the next release).

/etc/nginx/sites-enabled/pat-proxy

https://gist.github.com/martinhpedersen/361ae48cc66624118dce3e5e6888f239

@blockmurder - Thank you. I will check out jwt-go when I have some spare time :)