seisatsu / DennisMUD

Dennis MUD - A multiplayer text adventure sandbox engine where the players build the world with in-game commands.
https://dennismud.xyz/
MIT License
47 stars 6 forks source link

How to handle lost password ? #91

Closed jabossu closed 3 years ago

jabossu commented 3 years ago

I wanted to try your project as I love this kind of stuff. Your implementation seems great. Not even a single day after creating my account, I lost my password. SO ! Here is my first feedback : you should think of a way to handle ---idiots--- users who have this problem. Here are my two cents :

  1. You could ask for a mail address at registration, like ifMUD, and use that to reset a password. I dont like this solution for two reasons : a) Their way of doing it is unsafe, as they send the unecrypted password in a mail. User who reuse their password (and they are many) are exposed because of this procedure. b) It requires the host to implement a registration/rest form, which is different of your way of doing it directly in the MUD thakns to the register command.

  2. You could implement a "secret question" that allows user to reset their password : the rester command could ask 4 parameters instead of 2 : register login password "<question>";"<answer>" ; you could even make the last two optionnal, but necessary for recovery. Secret question are an unsafe way of authentification, but hey : it's a MUD, you can get away with low security. This, IMO, would be the best, as you keep it going through the same interface as the login and register commands

seisatsu commented 3 years ago

I have given this some thought, and I also disliked the idea of using email, mostly because sending email can be difficult for the average user to set up. Please email me at seisatsu@seisat.su and I will reset your password.

I will try to prioritize a decent way of recovering lost accounts.

seisatsu commented 3 years ago

Future registrations will receive a 6 digit recovery code they can use to reset their password without logging in. You can also get your current recovery code while logged in by using the recovery command with no arguments. You are warned to write down your code during registration.

Usage: recover [<username> <code> <newpass>]

jabossu commented 3 years ago

I'm amazed by how fast you were to implement a solution ! Great work ! Your way to solve this is not a bad idea in the meantime : I'm sure this implementation will help a portion of user to recover their password.

However, I don't think it will solve this issue. Here is my reasonning : if a user lost his/her password that he/she chose, it seems likely to me they will also loose a randomly generated 6-digit code. You could send this code by email to aleviate this, but that brings you back to the previous issue of implementing a mail server for average hosts.

Even allowing user to choose their 6-digit code at registration wouldn't, in my opinion, be such an improvement : they will (and by "they", I mean "we") forget it al the same, except if they reuse the same code elsewhere, in which case it's a security weakness coming from the user. In this scenario however, the user password would remain a secret to the attacker, which is a great improvement.

I believe (but might probably be wrong) that a secret question / answer system could be implemented in the same way you implemented this digit code and would solve this issue. (After reading the source code, it's obvious to me why that's not the case : your solution avoids the need of storing any information in a database, while my suggestion requires to do so.) I though about it a little under the shower, and came up with this mode of operation :

  1. The user register
  2. The user connects for the first time.
  3. They are informed of the existence of recovery command, which will allow them to register a clue and a secret answer to reset their password. They are made aware that this step is optional but recommended, as recovery will be harder / impossible if they don't take it.
  4. ❓ Bug the user on login, in the finger command output or anywhere else about their unrecoverable account with a "shy" and short sentence about them not doing it ? (This might be overkill, but without it, most user will forget to register a clue & answer)

I'd love your take on this : in my opinion, it shouldn't be too hard to implement and would help most user to recover their account, but you know your project more than me and might see a problem that I missed. In any case, it's great to see such life in your project ! You addressing such issue now will definitly be a big plus, as such problems will happen more and more as the userbase grows. It'm really interested in your work and how this little pearl will evolve !

jabossu commented 3 years ago

I went to check your code and your way of implementing the recovery, and it's clever ! Using a hash of the user's password is a brilliant way to generate a pseudo-random code in a predictable way without the need of storing it in a database. I also like your way of handling brute-forcing.

IMO, your way of doing it is good enought for now, where the userbase is small and users are dedicated players. I'd love to try and implement the suggestion I made earlier later on, when I get the chance to code a bit. Expect a pull request from me !

PS: great job commenting your code, it's very readable, love it 👍

seisatsu commented 3 years ago

Thanks! I tend to take months or years long breaks from projects, so heavy commenting helps me come back to it as much as I hope it'll help me attract more developers (and modders) down the line. I'll take a look if you put in a pull request, and will consider a security question as an alternative.

I am worried however that users who don't write down their recovery code when asked to also won't bother to set a security question if doing so is optional. I haven't added the ability yet for a command to initiate a dialog with the user, e.g. start asking additional questions and taking additional inputs before returning to the main context. Once I do, it should be possible to ask for a security question and answer during the registration process, or make the user enter their password twice. This sort of capability is already planned for #45, but it's low priority right now.