conradkleinespel / rooster

A simple password manager for Windows, macOS and Linux.
Apache License 2.0
151 stars 23 forks source link

Check password strength with "rooster weak" command #20

Closed conradkleinespel closed 6 years ago

conradkleinespel commented 7 years ago

It would be awesome to have a way to see if we have any weak/hacked passwords in our Rooster file.

What do you think ? Please post your thoughts here before working on this issue because we have to agree on the solution before we start coding.

My thoughts:

haze commented 7 years ago

downloading a 5gb file is totally out of the question here, I believe however that most databases that have been leaked from haveibeenpwned and other sources often store the hash, maybe we could check that way?

conradkleinespel commented 7 years ago

@hvze How would that work ? Genuinely curious 😃

conradkleinespel commented 7 years ago

I was just pointed to http://weakpass.com/. Might have some good stuff

conradkleinespel commented 7 years ago

Just noticed this which might be useful: https://github.com/jthomas/serverless-pwned-passwords

haze commented 7 years ago

That looks like it would either require a tedious setup for the user, or a potentially costly setup on our end

conradkleinespel commented 7 years ago

@hvze I totally get where you're coming from. Rooster has to stay simple to use for the user ! 👍

That being said, maybe there are ways we can make that setup as easy as possible, or even transparent.

yamnikov-oleg commented 7 years ago

Rooster could check the password for some easily-codable patterns, like "not enough diversity in symbols" or "too short". Contributors would add new patterns into the "check list" over time. We could even embed a small English dictionary of a couple of thousands words into the binary: 20kb of extra size would not burden users much.

I know that Rooster positions itself as a product for geeks, and geeks should not create that weak passwords in the first place. But when you have a storage of 100 passwords on different sites you might not remember that there is some old weak password among them. Also, Rooster could teach basic password security principles those users, who don't follow them yet.

Additionally, since Rooster keeps track of when passwords were stored, it could notify users to update an old password once it reaches an age of a couple of years.

haze commented 7 years ago

I like @yamnikov-oleg's idea of letting users know when the passwords hit a certain age, and I do like the password strength test suggestion.

Would it be nice to have a disclaimer at the README asking if anyone is willing to PR a certain check for strength? We could style it like zxcvbn check if anything.

conradkleinespel commented 7 years ago

@yamnikov-oleg @hvze

This message is a bit long. Why? Because I immensely appreciate your contributions and feedback, so I want to make sure I respond in as much detail as possible.

Common words / dictionary

In essence, the zxcvbn crate checks some common words and patterns. I'd rather we improved the zxcvbn crate (reducing 3rd party dependencies for instance) than reinventing the wheel regarding dictionary checks, especially since zxcvbn comes from Dropbox initially and probably works very well for most users (otherwise, Dropbox wouldn't be able to use it).

@yamnikov-oleg suggested vendoring dependencies to make the crate easier to review on changes. I very much like this idea. https://github.com/conradkdotcom/rooster/issues/28#issuecomment-322793473 👍

Additional checks

I like your idea to add custom checks in specific cases that zxcvbn does not handle.

But, @hvze, checking for old passwords is not useful and will create noise for the user. Troy Hunt explains this way better than I could so I'll just quote him here:

I had an easy way of remembering how long I'd been using a password for in my previous corporate job: I'd take the number in it that I incremented every time the company forced a quarterly password rotation and divide it by 4. I got about 6 years out of that particular password, only ever changing 1 or 2 characters at a time. If you're working in an environment that mandates regular password changes, you're very likely doing the same thing because it's an easy human control to deal with a technology requirement that's seen as an impediment. — Troy Hunt

I see some cases where I think we could have custom checks to improve security though. @hvze, I am with you on making it clear in the README that everyone is welcome to contribute checks they might need or find useful 👍

For instance, I recently switched from a 2048 bits RSA private SSH key to a 8192 bits key. I believe that 2048 is getting to small as computing power increases. I would have liked Rooster to warn me about things like "Hey, you use a 2048 bit key, 8192 is better".

This poses another problem though: how do we make sure that Rooster gives out updated information even when you don't upgrade Rooster to its latest version? On a strictly opt-in basis, I think that calling a webservice for these things would be useful here.

Sum up / questions

To sum up:

Questions:

haze commented 7 years ago

On the topic of a web service, I feel like that could be another project entirely. Even if it did start out as a rooster add on, it could easily be flushed out to something more complex. I know you very wary about security, and having a web service can be very vulnerable to attacks. You can be very creative with how you perceive what can happen with that. However, I feel like web services are the only real way to keep the client at a single state while still providing updates.

What are your thoughts on depending on GitHub alone? It's free to host a repository and many projects use the service for callbacks and more. Checking for updates on a sub project that has a bunch of user-contributed checks would make it easier for people to contribute and have rooster check for updates. It's also hosted in a static spot, and the only vulnerability is either GitHub becoming insecure or the repository maintainer losing their account.

Custom check wise, I feel like the advocacy for UTF-8 passwords is a must. On the off chance that only ASCII characters are allowed I feel like checks for strength based on character frequency (seeing how close characters are based on keyboard layouts) and more would also fare well. There should also be checks against common words, and also substitutions that can easily be guessed/cracked. This idea also ties in nicely if we do end up having a custom zxcvbn, as we can modify it to our liking to include both custom user checks and dictionary checks.

yamnikov-oleg commented 7 years ago

How do we make sure custom checks stay up to date even if you don't upgrade Rooster? What do you think of the idea of calling a webservice on a strictly opt-in basis for that?

I think that making weakness checks completely dependant on network connection would make Rooster's UI slower. The latency is not always ideal, and the web service might perform slowly under stress, which would worsen user's experience. Though this problem could be solved by isolating network-using functionality into a separate command like rooster weak. Or by deferring all network requests to the end of a command, so that user wouldn't have to wait to get the task done.

Besides, I don't think that hardcoding some checks into Rooster is a bad idea. It's fast and easy on both developer and user sides, and it works with no internet connection. Character frequency analysis (as proposed by @hvze) could be hardcoded :) These checks would not update very often so it's not critical to have every user have the latest version of check list.

Webservice though could be very useful for large dictionary checks and for looking up in compromised passwords databases. I agree with security concerns of @hvze, but I'm not sure how to make it safe. There are many sofisticated ways to validate service's identity, like SSL, but the identity can be stolen, if a hacker gains access to the server.

Well, the service could be designed in such a way, so it wouldn't need user's passwords in plaintext, just hashes. Passwords databases could be converted to databases of password hashes. Though no checks could be performed on a part of a password.

On the topic of a web service, I feel like that could be another project entirely.

Indeed, if such a service would be developed, it might not be bonded to Rooster directly, but might be available for public use.

What custom checks would be useful to you?

If zxcvbn gets to be installed, it should cover most possible strength flaws :) But if not - it would be nice to have Rooster calculate entropy of passwords on its own.

conradkleinespel commented 7 years ago

Hello @hvze and @yamnikov-oleg ! Thanks for your awesome feedback here.

Sorry for the delay and long wait time. I am on vacation until Wednesday and have been doing little coding lately (except for some unit/integration tests). I'll get back to you in detail next week.

Have a great week-end !

conradkleinespel commented 6 years ago

@hvze @yamnikov-oleg

Sorry again for the delay. Here we go!

Webservices

Rooster can use webservices to get data, but the CLI version of Rooster will never send any password information to a webservice and Rooster will never be able to install new stuff from a webservice. Passwords are too critical IMO to allow that. If you want to install stuff that's fine, but Rooster won't do it for you. Beeing able to build new tools on top of Rooster is important though (more on that below).

On the topic of a web service, I feel like that could be another project entirely.

Yes, totally, good point! Let's keep that appart!

like SSL, but the identity can be stolen

Yes, and that is why the CLI version of Rooster (aka the rooster command) will never send any password data to a webservice. Never. However, there will soon be ways to extend Rooster with the librooster project (https://github.com/conradkdotcom/rooster/issues/39), so building new tools on top of Rooster will be easy.

So maybe as some point there will be a rooster-cloud-sync tool that you can use to save your passwords online. Or maybe there will be a rooster-update tool that will automatically download the latest version of Rooster to your machine. Putting network stuff inside separate tools means you have strong guarantees that Rooster itself doesn't communicate with the network.

the service could be designed in such a way, so it wouldn't need user's passwords in plaintext

I have never read about a method that would allow to do this securely. If you know of one, please post links so we can learn about it ! 👍

UTF8

Having checks for UTF8 could be cool. But rewriting an entire library instead of using zxcvbn only because of UTF8 would take a large amount of work (both upfront and for maintenance). In addition, zxcvbn already checks for repeated character sequences.

One of Rooster's goals is to keep maintenance cost low so that Rooster never becomes unmaintained. That means trying to cut down on custom development when possible.

I do understand your need for more strict password strength policy. More on that in the conclusion down below.

Keyboard** layouts

Close characters based on keyboard layouts are not useful to the attacker if the password is autogenerated, which it should be. In addition, given the variety of keyboard layouts, especially among folks like us that like code, I think that checking for strength based on keyboard layout will add unnecessary complexity to Rooster with little benefit.

I do understand your need for more strict password strength policy. More on that in the conclusion down below.

Network latency

Rooster will never make the network mandatory to run any command. Rooster is offline by default. Anything network related is optional, secondary and strictly opt-in.

Conclusion

Based on your feedback, I think we should:

rooster weak

Let's build a rooster weak command that displays weak password using zxcvbn.

How does that look? What would you want rooster weak to display?

Here's the most basic version I can think of. But ideally, I'd like rooster weak to help me generate new passwords for the ones that are weak.

$ rooster weak
You have 2 weak passwords:
YouTube 10 days to crack
Google  2 days to crack

librooster

Let's build a librooster crate that gives access to Rooster's functionnality from a Rust library. This means that you can import librooster in your Cargo.toml and make custom software that works with your Rooster file.

I'll make a separate issue for that. (edit: https://github.com/conradkdotcom/rooster/issues/39)

conradkleinespel commented 6 years ago

I've just updated my previous post to explain what I meant when I said that Rooster would never call webservices. It means that the rooster command line tool (the one we have today) will never call the network. But it will be possible with librooster (https://github.com/conradkdotcom/rooster/issues/39) to easily build stuff on top of Rooster, so building new features that make use of the network will be possible.

conradkleinespel commented 6 years ago

@hvze @yamnikov-oleg Just spent a couple of hours reading through 3rd party dependencies' code and pushed a first version of the weak command on master. If you have any feedback, need changes or want to improve the feature, please open a new issue or PR 😃 thanks again for your feedback so far !

@hvze if you'd like to add a flag like utf8 so it shows passwords that don't contain utf8 characters as weak, feel free to make a PR 👍 we could then do something like:

rooster weak --utf8

And instead of using --utf8, what would be cool is to have ROOSTER_UTF8=1 environment variable that would do the same as --utf8, so you wouldn't have to type the --utf8 everytime you check for weak passwords.