What Is the Shadow Password Field? * and ! Explained
The shadow password field decides how a Linux account can authenticate. Learn what $6$, * and ! mean, and why the difference matters for SSH.
The shadow password field is the second colon-separated field in each /etc/shadow line, and its contents decide how an account can authenticate. It holds a salted hash, or a marker such as an asterisk or exclamation mark meaning no password should work. These values look interchangeable but behave differently, and the OpenSSH password bypass on Alpine turned one of them into a way in.
What is the shadow password field?
The shadow password field is where a Linux system stores the password information for an account, usually as a salted hash. It is readable only by privileged users, and login programs compare a hash of what you typed against this value.
The shadow(5) manual page describes a line of nine colon-separated fields: login name, encrypted password, last change date, minimum age, maximum age, warning period, inactivity period, expiration date and a reserved field. Only the second one decides whether a password can work at all.
A real hash carries its own parameters. In a value such as $6$abc$k2P9, the $6$ selects SHA-512, abc is the salt, and the remainder is the computed hash. A $5$ prefix selects SHA-256. To check a login, the program hashes the attempt with that same salt and compares the two strings.
What does an asterisk mean in the shadow file?
An asterisk means the account has no password that can ever match, because it is not a valid hash result. The account cannot log in with a Unix password, but it can still log in by other means, such as an SSH key.
The convention is old. The researcher behind the OpenSSH finding traces it to a 1980 BSD password file, where an asterisk marked an account nobody should use. Today you will find it on key-only deploy users, on service accounts, and on root in Alpine base images since about version 3.16. Alpine's advisory notes that adduser without a password or usermod -p '*' produces this state.
What does an exclamation mark mean in the shadow file?
An exclamation mark at the start of the field means the password is locked. Characters after it are the previous value, so unlocking restores the old password.
The shadow(5) page treats ! and * alike for password login: neither is a valid hash result, so the user cannot use a Unix password, though they may log in by other means. In practice the software reading the field matters. Alpine's advisory says accounts with ! cannot log in with a password or a key under its PAM-less OpenSSH package. That is why Alpine moved root from ! to * in version 3.16: its 2019 fix for CVE-2019-5021 locked root with !, which also blocked SSH keys on cloud images.
What does an empty password field mean?
An empty field means the user can log in without a password. Some applications that read the shadow file block access in this case, but you should not count on that.
This is the state behind CVE-2019-5021, in which Alpine's Docker images had no root password at all. An empty field is the one value here that should always trigger an alert during an audit, unless a documented kiosk or lab reason exists.
Why the difference between these values matters
All these markers rely on one assumption: no hash output can equal the marker. The OpenSSH flaw broke it. Under musl libc, crypt() returns the string * when it fails, so a failed hash can equal a stored asterisk. Alpine lists accounts with ! as out of scope, and the failed hash returns *, not !.
The lesson is broader than one CVE. Treat these values as conventions that depend on the libc, the login program and whether PAM is in the path. Musl and glibc behave differently here: the researcher notes Debian's libxcrypt returns *0 on failure. See why musl vs glibc security differences affect patching for what this means for fleet planning.
How to audit shadow password fields
As root, review the second field of /etc/shadow on each host and sort accounts into four groups:
- Real hashes: which users have them, and do they still need password login? On the affected systems, a single account with a
$5$or$6$hash made every asterisk account reachable. - Asterisk: expected for key-only users. Confirm each one has a known owner and authorized keys you can account for.
- Exclamation mark: locked. Confirm nobody expects key login to work if the host runs OpenSSH without PAM.
- Empty: investigate immediately.
Do not stop at the file. Directory users arriving through musl-nscd have no shadow entry at all, and Alpine lists them among the accounts exposed by this bug. They will not appear in a local audit, so pull the list of who can log in from the directory side.
Resist the urge to bulk-replace * with ! as a fix. Under Alpine's PAM-less package, that blocks key login too, and you can lock out your own automation. The correct response to the bypass is to update openssh and restart sshd, or to disable SSH password authentication if you cannot update yet. Both close the hole without touching account state.
What to record in your baseline
Record the expected state for each account class in your configuration management, then alert on drift. A new hash appearing on a server that should have only key users is worth a ticket on its own: on Alpine tiny-cloud images, setting a console password was enough to make the default alpine account exploitable. Build the check so that it reports the field type rather than the value, and keep hashes out of tickets, logs and chat.