JonasunderscoreJones / McWebserver

Run a Website and powerful API alongside your server
https://modrinth.com/mod/mcwebserver
Creative Commons Zero v1.0 Universal
10 stars 3 forks source link

Add basic auth? #8

Closed danya02 closed 6 months ago

danya02 commented 6 months ago

On my server hosting platform, you can only access files via FTP, which is fairly slow. I'd like to use some kind of mod to access the server files in order to run backups. This mod looked interesting, but I'm worried that all of the server files will be accessible to anyone to download: some of them contain secrets such as database connection passwords. Normally I'd put a reverse proxy in front of the server, but in this case that's not possible.

Would you consider adding support for requiring login credentials in order to access the files? I know it's not entirely secure unless HTTPS is used, but it'll work as a defense against casual port scanning attacks.

JonasunderscoreJones commented 6 months ago

Interesting point. I'll consider it. Using the server directory as the Webserver root is bad practice though, I hope you're using the backup directory. I'll get back to you within the next week.

JonasunderscoreJones commented 6 months ago

So this is what I did: image On Top is the line in the config file that sets the password. It's stored in plaintext, thus not very secure but you need the password to access the file (if you ever chose to use the server directory as the server root) so it should be fine. The bottom shows how to access it. I didn't use fancy cookies to check your session or anything but this does the trick. If you don't provide a correct password, a 403 (Forbidden) error is returned. This kind of breaks websites in a way that if an html file requires css or pictures from the same server, you'll need to add the suffix to the file link in the html file or else they won't work.

EDIT: Something that might not be clear on the screenshot is that the suffix on the link is ?auth=password (not with the forward slash in front)

You can check out the changes in the password-impl branch

Let me know what you think.

danya02 commented 6 months ago

Recently you've added tokens as a separate feature. Instead of adding passwords on top of that, maybe you could extend the tokens by adding a setting that says "files can only be accessed with a valid token" and also making it possible to create tokens that never expire? That way the two features are unified, and it also avoids putting the password in GET parameters (which is a bad place for them because that gets stored in the browser history).

That's what would work for my use case anyway, with machine-to-machine communication. For humans, you would probably use true HTTP Basic Auth. Here, you return a 401 if you want a user-password pair but don't receive it, with a WWW-Authenticate: Basic header indicating that you'd like the password, and then the browser asks the user for the password and sends that with every following request (even if you navigate in the browser). It's not a cookie, but it persists during a single browsing session, while a GET password doesn't if your HTMLs don't also include it.

This may be a bit too complicated to do with your current setup, where you manipulate the raw TCP stream of HTTP/1.1 messages. Are there any libraries you can use to do this for you instead?

JonasunderscoreJones commented 6 months ago

Yeah this is the proper way, I was thinking that my concept still makes it possible to use the webserver for other web content but that kind of defeats the purpose. True, I could just use the authentication token. Keep in mind, that managing tokens is only possible in-game. This shouldn't be complicated to implement on the webserver side. There are probably libraries but I have already implemented the token authentication for v2 of the API, therefore I can just copy paste that. One day, I might replace all this code with proper libraries.


Here is what I did: image You are now required to provide a Token (in this case with the value "something") generated from the /mcweb command (ingame). I plan on implementing a whitelist and blacklist feature for this command to further control access to generating new tokens since at the moment all server operators with permission level 4 have access to it. The Token requirement for the webserver is of course again toggleable with web.require_token

Commit: 54188d7

Tell me what you think!

danya02 commented 6 months ago

That's not really how Basic Auth works: the string included there should be a base64-encoding of the provided username and password. A browser won't just put your token there, even if that's what you type, because it's base64-encoded. Also, this breaks existing clients because they were sending an Authorization: Bearer before and now that doesn't work anymore.


I think that with your current architecture, it's gonna be rather difficult to set it up so it both fulfills my need and also works for your original goal: you'd have to have a lot of different hacks around to manage all the use-cases. If I have enough free time, I'll fork your repo and replace all the features I don't need with the ones I do.

JonasunderscoreJones commented 6 months ago

fair enough, I'll leave the change of optional token Auth for the Webserver in and publish it with the next Minecraft release.

I initially chose against using user and password Auth for less complexity. having a single token to authenticate is more than enough for the average user and if you really need something more secure, a Minecraft server isn't the best hosting platform for such data.

Hope you'll find a way to get what you need. Cheers!