kanayak123 / pyadselfservice

Easy and secure web based password change portal for Active Directory user accounts.
https://technokan.blogspot.com/2016/10/web-based-python3-password-reset-tool.html
21 stars 7 forks source link

Resetting passwords does not honour password history policy #1

Closed kanayak123 closed 4 years ago

kanayak123 commented 7 years ago

In AD there are two types of operations to change a user's password - a change, which can be executed anonymously because it requires the old password as part of the request, and a reset, which does not require the old password and must be done by a user with access to be able to reset passwords for the account being targeted. In this case, pyadselfservice is doing the reset operation, without knowledge of the user's old password but while authenticated as a service account with the needed rights. From the perspective of AD, the password is being administratively reset; password history is never enforced in this case, since the administrator doing the reset shouldn't know the user's old passwords.

kanayak123 commented 7 years ago

Found a work around to over come reuse of current password. Released in the current commit.

prateekappviewx commented 7 years ago

Hi Amith is there any way through python if i can 'JUST' validate against Active directory if password user is going to set is adhering AD policy or not. I know i can use regex to check password length,complexity etc but what is killing me is 'password history'. Also i don't want to change right away once user has given new password to reset i want to show "OK" or "Fail,password complexity or password history not met" or something similar.

kanayak123 commented 7 years ago

Hello Prateek Password history is validated only when a user tries to change his password through his current password. Means, there is no way python can honour AD password history unless user remembers his current password. The idea behind pyadselfservice is to allow user to reset password when he doesn't remember his current one. To achieve what you need, I can think of 2 methods:

  1. Ensure you allow change password through portal for users who remember their current password. Just use some free tools like manageengine.
  2. When users don't remember their current password. The workaround I can think of is, in the script, first reset his password through a privileged account, use that new password as current password and the password entered by user as new password. Its bit complex but works.
prateekappviewx commented 7 years ago

Thanks a lot Amith for replying. First of all i didn't want to reopen this ticket as it has nothing to do with pyadselfservice. I just wanted your help as we are creating inhouse automation tool based on Jython (Java+Python). Use case is if user forget or their password expires they raise request from their manager or colleagues machine which sends them OTP on mobile then the user himself/herself give the password that they want to reset to.

1)Now since we are using admin account to reset it is not following active directory password policy (i guess it is by design). So when user gives his/her password how can i verify the password history compliance? Is there way to check that?

2)If there is no way to verify what is the way through python to change password in adherence with password policy (i.e simply reset password if in compliance else fail need not to verify)

The reason i asked for validation thing the way our tool is designed if we are able to check password history and if user has given previous password our tool will fail the request and user need to raise request again which would be pain for them as they would complain cant you validate if we are giving one of our previously used password

kanayak123 commented 7 years ago

Hey dont worry about reopening, it was for my reference :) The design of the tool needs to be tweaked such that it goes through a flow where you can achieve everything you need. I will just conceptually try to explain. You can may be tweak your current design and code.

I am skipping the OTP part, that is to validate the authenticity of the user. In the user interface provide password field. The user will enter the password that he wants. You can use the password meter to warn about password complexity. Use this library http://ldap3.readthedocs.io/microsoft.html In your backend script, pass this twice "extend.microsoft.modify_password(user, new_password, old_password=None)" to DC First, bind to DC as privileged user and reset the password with some random password Second, bind to DC as the user who wants to reset password. new_password will be the password that he entered in password field in the interface, and keep the old_password as the random one set above in first. When u do that if the user is trying to reuse password that was in history, the library will return the message with reason. Format the message and display it and allow retry.

This is a workaround that I can see. It will work but.

prateekappviewx commented 7 years ago

Thanks Amith again for replying. Ok i get the idea but in this case if my AD is having policy to keep past 5 (for example say 'n' times)password history would it become like having password history as 4 (n-1 times)?. Sorry for replying late

kanayak123 commented 7 years ago

You are right. Thats why its a workaround, not solution. I don't see legitimate solution through python for password history. The roadblock is AD design and its designed rightly to secure it.

prateekappviewx commented 7 years ago

Thanks Amith, I have one more worry if it is always going to be n-1 then we can resolve this. I can set AD to set to 6 instead of 5. But i exactly dont know how Active directory stores password. Consider the case::: Let suppose user is having past three password as P3, P2 and P1. Now through admin account if automation tool resets the history to T1(temp password ) the history becomes P2,P1,T1 . Now user by mistakes gives P2 in our tool for resetting. So AD will fail the request. So users creates same request again and our automation tool again reset the password to T1 first . So is now users history T1,P1,T1 or still P2,P1,T1. I hope it it is not very stupid question i dont know how passwords are stored in AD. I hope it is P2,P1,T1 but wanted to check if you know. Is there any official documentation from Microsoft which can shed light over this. If possible any help would be great

kanayak123 commented 7 years ago

As far as my understanding is, password reset done on a different account by a delegated/admin account will never overwrite password history. The hash is stored only if a user is changing password for his own account. You should google around and im sure you'll get million answers. But to see it practically, just test it and confirm yourself.