-
Notifications
You must be signed in to change notification settings - Fork 8
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
Improve the authentication / sign-on story #30
Comments
I would think that for now, you should be able to replace the underlying crypt() builtin with some sort of hash, and have that builtin ignore any salt passed to it. If I understand the way the whole thing works, this should still work, without modifying any MOO code. The code crypts a password, gets a hash back, stores that, then when it needs to check it, it crypts the supplied password, also supplies the first two chars as salt (which a new crypt builtin would ignore) and gets a hash back, and if they match, we're good. |
You're probably right it would be possible to make it work that way, but I'm still not convinced that having passwords in-core is the right story at all... and I'm pretty sure what we're describing here is not good security practice in this day and age. And there's no reason in this day one couldn't support e.g. OAuth2, with just tying the 'player' object ID to external credentials, and rely on other, better-structured/audited, etc. security services to carry the weight & risk. |
All this is true. However, if you did make the crypt() builtin hash instead of encrypt, you could have an unmodified LambdaCore, right out of the gate, that doesn't store passwords (not even crypted ones) in the database. |
The code actually supplies the entire crypted password as the salt (even though the documentation for crypt() says not to do that), and the crypt() function itself is responsible for reducing it to two characters. Which I guess means you could have crypt() implement whatever the current standard for password hashing is and there's no reason that wouldn't cut it. Personally I don't understand the arguments against storing passwords in-database - my proposed scheme is basically identical to the way that any other login-requiring website works. I thought the idea of MOO was to do as little as possible in-driver and as much as possible in-core. |
All RPC requests to the daemon now have attached Client and Auth PASETO tokens. The former is for validating that the RPC connection is who it says it is. The latter is for validating that the user is who they say they are. It is now possible to get an auth token from logging in through `/ws/auth` endpoint. Though there's nothing yet in place to use it. The idea is that websocket connections (and HTTP generally as well) will work this way: 1) auth and get a PASETO token for the player that is auth'd to. 2) subsequent calls to the system -- such as a websocket attach, or a request to retrieve a property or verb, etc.) will attach the auth token in a `X-Moor-Auth-Token` header on each request. TODO: * validate the player inside the Scheduler/Task layer before launching a task (and return E_PERM etc.) * add a websocket connect that uses the authorization header to skip login, and remove the Basic-Auth (which can't work from a browser now anyways) (#30)
Hi. Looking deeply into this, I wonder why not using SSH instead? While most clients are very well able to connect via telnet, they cannot utilize all the neat features of SSH, yes, for that it would be necessary to build some sort of local proxy to translate from the outbound SSH-connection to an internal telnet connection, but this way all features of SSH could be used, including public key encryption, SSO etc. Using this, I would guess it is possible to use the same SSO-backend for both http and pseudo-telnet connections. Just some thoughts from a user perspective. Yes, it breaks compatibility with telnet, on the other side it solves almost all security issues. Telnet is a security risk by itself anyway. |
Sorry to not reply to this for a while. I have been busy with real, paid, work, and haven't had time to give to moor in a while. But to update, what's actually happened here is that I've chosen to prioritize the web/websockets story over everything else. The expected primary mode of interaction with the moo hosted in moor is to be over HTTP and websockets (and, likely, in the future webtransport). The line-command oriented style of LambdaMOO is supported over websockets (which are kinda like 21st century "telnet", really), but verb invocations, property access, and And because of that what I ended up implementing for authorization is the following: in Then the actual sessions -- either websocket, or HTTP -- have to provide a valid PASETO token for each connection. For the websocket, this is passed as a query string parameter before the websocket upgrade. For HTTP POST/GET it is passed in HTTP headers. (Browsers unfortunately do not support custom HTTP headers for websocket connections, which boggles my mind). This was all implemented back a couple months ago, along with a primitive web client that lets you connect, authenticate, does the command loop over the websocket, but also has a prototype (but incomplete) Smalltalk-style object browser and syntax highlight MOO verb code editor (using the same editor that drives VSCode). But I have not had time to write it up and document it yet. I still consider the last bit prototype phase. |
LambdaMOO cores'
connect
function uses a variant of the Unixcrypt
function, ala old Unix passwd files, and stores the passwords in-db.For compatibility with existing cores (and to make servicing existing
telnet
clients feasible), it's necessary to keep this process for now. But this isn't going to cut it as a security story.Some kind of SSO story & auth token is going to be needed. For the latter, one option is
JWT
, another isPASETO
, which sounds more promising.Then the websocket connection (and any HTTP sessions generally) will need to be authenticated with this token before client connections can proceed.
The long-term future for the
telnet
modality will need to be thought about in this context.Not a requirement for 1.0 (LambdaMOO compatible) release.
The text was updated successfully, but these errors were encountered: