OpenPasswordFilter icon indicating copy to clipboard operation
OpenPasswordFilter copied to clipboard

Add feature: partial password matching

Open mtlkexpy opened this issue 8 years ago • 10 comments

I wanted to be able to match on a substring of the password but didn't want to removing anything or change the any functionality for existing users, so I thought I'd try to keep things separate as much as possible. I ended up creating two new dictionaries to add the functionality and added the checks to the contains function.

  1. partial: Just loops through the dictionary and if an entry is matched anywhere within the password string the contains function returns true. I'm converting the strings to lower case before matching.
  2. excluded: just the reverse of the original contains function - returns false if an entry is matched. I thought it would be useful to be able to exclude a password from being filtered, especially when using partial matching.

So the contains function should check the excluded dict first, then exact, then the partial dict.

I renamed the words (opfdict.txt) dictionary to exact (exact.txt) try to make the names a bit more descriptive in what they are filtering, but to prevent breaking current installations the service will check for opfdict.txt if exact.txt is not there.

I also added a check to make sure the files exist before opening the StreamReader; if any of the files are missing the service will still work, for example, if only the ofpdict.txt file exists, it will only use that file.

mtlkexpy avatar Feb 21 '17 20:02 mtlkexpy

I'm curious how you see the use case for the "exclude" list. It seems like creating a list of likely in use passwords, which might be a liability. I'm trying to understand when it would be used.

For example, say a user tries to set a password, and the system blocks it because it matched a substring. So they call in to support, and say, "I'm trying to set my password to x, but it's failing." Would that be when support adds that password to the list? Doesn't this knowledge and documentation of the password seem like it's going to be some sort of policy violation in itself?

On the other hand, if someone chooses a substring match that creates legitimate false negatives, then I would think that it's just been selected poorly. Partial matches could be very powerful (like preventing someone from using the company name anywhere in a password), but if misused could be a real problem (e.g., if you added "a" to the list!). But that seems like a risk / complexity that a domain admin should be able to take on and try to make intelligent choices.

What do you think?

jephthai avatar Mar 13 '17 15:03 jephthai

My thought process behind the exclude list is to be used together with the partial list for provisioning new user accounts, e.g., bringing on many new users at one time such as a new classroom of students or a company acquisition. Set all new user accounts with a generic password that they would have to change at the first login; Password history requirements would prevent that password from being used again, and then partial matching would prevent the user from changing it to "password"+1, etc.

mtlkexpy avatar Mar 13 '17 15:03 mtlkexpy

That's effectively a password whitelist, and that does not give me warm fuzzy feelings. Why not, in the case of creating a batch of new accounts with a generic password, simply select one that passes the filter in the first case?

brockrob avatar Mar 13 '17 16:03 brockrob

It is just a password whitelist - in this case though, it's one that I control with the password history requirement.

The problem with choosing one that passes the filter is that users are terrible at thinking for themselves and just end up appending a number to the password I've assigned. I wan't to be able to assign them a password that they can't re-use in any form. If they're going to pick something and just continue to increment the suffix every time they need to change it, at least they would need to pick their own password and not use the temporary one I've assigned as a template.

mtlkexpy avatar Mar 13 '17 16:03 mtlkexpy

Ah, that makes more sense.

brockrob avatar Mar 13 '17 16:03 brockrob

Ultimately, @brockrob did a better job than myself at the partial/contains matching (I'm certainly no expert, just a tinkerer), so might as well close this PR. If you have any interest in the whitelist option I can clean it up and make a separate PR for it, otherwise I'll just leave it alone.

mtlkexpy avatar Mar 13 '17 17:03 mtlkexpy

Perhaps a better idea would be to allow a configurable list of users (or security group) to bypass the check? Then your domain admin account creating these users could set the initial password to whatever it likes. There's an issue #6 that'll get more data (username particularly) into the filter service, so once that's in place this would be a trivial addition, and seems a more reasonable approach to the problem than a password whitelist to me. What do you think?

brockrob avatar Mar 14 '17 10:03 brockrob

I agree that is a better solution than the password whitelist, and would certainly solve the problem I was trying to address.

mtlkexpy avatar Mar 14 '17 13:03 mtlkexpy

Or perhaps not. Seems the DLL isn't aware of any more than the account whose password is being changed. :/

https://msdn.microsoft.com/en-us/library/windows/desktop/ms721878(v=vs.85).aspx

brockrob avatar Mar 15 '17 17:03 brockrob

Hi There,

I have a problem with this Open Password Filter.

I've setup a test environment and used the all-in-one installer. Upon creating my first dictionary, it rejected one password, once.

After that, everything was possible.

Your readme is not up to date with your changes, so I snoofed arround to get things going. It is a succes, when a user uses the CTRL ALT DEL option. Yes, then it's rejected. But not on a password reset from the AD-DC. You can choose any password you want.

How can I, or you program it, so that the initial password change is required to meet those strengths from the exact, partial and excluded .txt ?

Love to hear from you,

Kind regards,

Martijn Kamminga

ghost avatar Dec 04 '17 15:12 ghost