Passwords in Active Directory attributes: the Description field anyone can read
It is one of the most frequent and most embarrassing findings in an Active Directory audit: a service account password written in the Description field "so we don't forget it". By default, every user in the domain can read that attribute. An attacker who compromises a single workstation only has to query the directory.
Why these attributes are readable by everyone
Active Directory is designed as a directory: by default, authenticated users can read most attributes of user, group and computer objects. That is what makes address books, applications and admin tools work. The downside is simple: anything written in an unprotected attribute is within reach of any account in the domain, including an intern's account or a compromised computer account.
Attributes to watch
| Attribute | Name in consoles | Risk |
|---|---|---|
description | Description | shown in every console, used as a reminder |
info | Notes (Telephones tab) | free-text field rarely reviewed |
comment | not shown by default | filled in by scripts or third-party tools |
userPassword | not shown by default | may hold a readable password depending on forest configuration |
unixUserPassword | not shown by default | legacy of Unix integrations, sometimes populated |
The userPassword case needs clarification. Depending on a forest setting (in the dSHeuristics attribute), this attribute is either treated as an alias for the real password, and is then not readable, or treated as an ordinary attribute. In the second case, which is the default for modern forests, an application that writes a password into it stores it as is, readable by anyone with read access. Some directory connectors and older LDAP applications still do this.
Keep other classic locations in mind as well: old Group Policy Preferences containing a password in SYSVOL, logon scripts, or poorly protected legacy LAPS attributes.
Finding the secrets
The search uses standard admin tools. A PowerShell query from the Active Directory module that retrieves the description, info and comment attributes of every user and computer, then filters on keywords ("pwd", "pass", "password", plus local-language equivalents), reveals most cases. For userPassword and unixUserPassword, the mere fact that they are populated is a warning sign: they should not be.
Do not limit yourself to active accounts: disabled accounts often get re-enabled, and a password written down years ago may still be valid on another account or system.
Cleaning up properly
- Treat every password you find as compromised: anyone could have read it, at any time.
- Change it on the account concerned and on every system where it may have been reused.
- Clear the attribute, then make sure the application or script that wrote it will not put it back.
- For service accounts, move to group managed service accounts (gMSAs) where possible, which removes the need to know the password at all.
- Store remaining secrets in a password vault with audited access.
What about confidential attributes?
Active Directory lets you mark an attribute as confidential (a flag in searchFlags): reading it then requires a specific control access right that ordinary users do not have. This is useful for custom attributes holding sensitive data. However, base schema attributes, including description, cannot be made confidential. The answer is therefore not to hide the password, but never to write it into the directory.
One simple rule. No secrets in the directory, whatever the attribute. Write it into your administration procedures and check it regularly, because these habits come back with every new contributor in a hurry.
What an audit checks
- password-related keywords in
description,infoandcomment; - objects where
userPasswordorunixUserPasswordis populated; - the
dSHeuristicssetting that governsuserPassword; - passwords in SYSVOL and logon scripts;
- whether passwords found in a previous audit were actually rotated.