Does replacing a bcrypt hash with an invalid hash result in no possible working password?

In terms of disallowing legitimate login attempts, it's fine. Unless you're using a very weird hash function, there won't be any values which map to -, and it prevents brute force attacks against the missing values if the database is stolen too, which is a positive (they were unlikely, given the use of bcrypt, but this applies even if the implementation is using a terrible method for storing passwords - pretty much anything other than plain text).

In terms of downsides, if the database is taken, it slightly decreases the security of other accounts - the attacker has fewer records to brute force. If they are paying attention, they should probably remove the records which are marked as inactive, but still. I did say "slightly"...

The other risks could be if there are any methods for access which allow bypassing the hash method for comparison (e.g. you have a legacy method which allows supplying the full hash for some reason) - in that case, if you aren't checking the active status carefully, it might allow access by supplying a dash. Ideally, remove this access method, if this is the case.


An invalid password hash (usually "*") truly disables password authentication, since there is really no way to supply a value that will hash to it. However, an invalid password hash does not "deactivate" the account if there are other authentication methods, e.g. by ssh private key. In fact, this is a common way of enforcing key-only authentication: an invalid password in combination with an ssh public key in ~user/.ssh. Therefore an invalid hash in the password column should not be interpreted as "account inactive", but "password authentication blocked".

If password access is the only path available, an invalid hash is arguably superior to explicit flagging because it does not need software support: if /etc/password had an activeuser column and I used it while leaving a valid password in the password field, some tools might ignore the activeuser field.


Certainly a big difference is that a user being flagged as "inactive" could still log in, except your server checks for the flag and handles the attempt properly. In addition, the flag may be removed, effectively restoring the original state, while changing the hash to "-" cannot be restored without save the password hash somewhere else. Depending on your application, this may or may not be desired behaviour.

A security risk is not created by this approach, as an attacker with access to your database could merely see that this user isn't supposed to be able to log in. As you correctly stated, no bcrypt hash can match "-", as the format alone doesn't match.

As schroeder stated in the comments, this is not a bad practice, but a common concept to prevent users from logging in, without modifying the login-mechanism to take your "inactive" flag into account (inactive users trying to log in are implicitly rejected).