Click forgotten password on your own site. If it emails back your actual password, the system stores passwords readably. Have them converted to salted hashes, then ask every member to choose a new password.

A column of readable passwords

Some websites keep their members' passwords where anyone with access to the database could read them: an email address in one column and, beside it, the password exactly as it was typed.

It is common in older booking systems, members areas and client portals, built years ago to a budget and still running because they work.

Nothing goes wrong while the database stays where it is. If a copy ever leaves, through a hacked site, a stolen backup or an old developer's laptop, every member's password goes with it.

And the damage spreads beyond your site, because many people use the same password for their email and much else.

Signs your site stores them badly

The first is the one anyone can test today. Click forgotten password on your own site. A system that can email you your password has it stored in a form it can read.

How a password should be stored

A properly built system never keeps the password at all. It keeps a hash: the result of running the password through a one-way calculation that cannot be run backwards.

At each login, the system runs what was typed through the same calculation and compares the results. If they match, the password was right.

Two details make the difference. A salt, a random value added to each password before hashing, means two members with the same password get different results.

And a deliberately slow method means that guessing millions of passwords takes far too long to be worth trying. Bcrypt is the usual choice, and PHP has included functions for it since version 5.5.

Weak scrambling is not much better

Some systems encrypt passwords rather than hashing them. Encryption is designed to be reversed, and the key usually sits in the same code, so a copied site often hands over both.

Others use an old, fast hash with no salt. For common passwords, the results can simply be looked up in published tables, and the rest fall quickly to guessing.

Either way, a developer asked how passwords are stored should be able to name the method. Encrypted is not the answer you want to hear.

Why reuse makes it everyone's problem

A list of email addresses and passwords is valuable because people reuse passwords. Criminals try each pair on webmail, shops, banks and social networks, automatically and at scale.

Your members area may hold nothing more sensitive than a booking history. The member's email account, opened with the same password, holds everything else.

Canadian privacy law already expects safeguards suited to the sensitivity of the information an organisation holds. Readable passwords are hard to defend under that standard.

A worked example

A braille transcription service with four transcribers turns menus, statements, manuals and course materials into braille and large print for its clients.

Clients log in to a portal built for it in 2009 to upload documents and download finished files. A few hundred accounts belong to restaurants, publishers, colleges and companies that send customer statements.

Testing a new client account, the office manager clicked forgotten password. The portal emailed back the password she had just chosen.

The developer now looking after the site found every password stored with a reversible scramble, its key in the same code. The welcome email had also been sending each new client their password since the start.

He changed the portal to keep only salted bcrypt hashes, converted every existing password in one pass, and replaced the emailed password with a reset link that expires after an hour.

The service then wrote to every client, explained the change in two sentences, and asked them to choose a new password on the site and to change it wherever else they had used it.

Converting what is already stored

Readable or reversibly scrambled passwords can be converted all at once, because the system can still read them. Each one is hashed, and the readable copy is deleted.

Passwords stored with a weak hash cannot be read, so they are upgraded as each member next logs in, or replaced through a reset.

The code that saves new passwords and checks logins changes at the same time, and so does every email that used to include a password. Sign-up, login and reset are then tested on a copy before going live.

Old copies hold old passwords

Converting the live database protects it from today. Every backup, export and test copy made before the change still holds the passwords in readable form.

Ask who has copies: the host's backups, a spreadsheet export of members, a former developer's working copy. Old ones that serve no purpose should be deleted, and recent backups kept where access is limited.

Asking members for new passwords

Conversion protects passwords from now on. It cannot undo the years they sat readable, so members should be asked to choose new ones.

Keep the message short and plain: what changed, and why. Rather than including a link, ask members to visit the site and use the forgotten password page, so the email cannot be mistaken for a phishing attempt.

Suggest they also change it on any other account where they used it. For many members, that is the part that matters most.

The counter-case

A site with no member logins has nothing to check. Neither does one where every account lives in WordPress itself, which already stores passwords hashed and salted.

A booking or membership service run by an outside company keeps logins on its own systems. It is still worth asking the provider how, in writing, but the change is theirs to make.

And a members area that few people use might be retired rather than repaired. Wherever logins stay, make sure passwords are stored as salted hashes, then ask members for new ones.

This week

  1. Click forgotten password on your own site.
  2. Read the emails your site sends new members.
  3. Ask your developer in writing how passwords are stored.
  4. Convert stored passwords to salted hashes.
  5. Replace emailed passwords with expiring reset links.
  6. Delete old exports and copies holding passwords.
  7. Ask every member to choose a new password.

Step one is the quickest answer to the whole question. If your own site emails you your own password, the rest of this list stops being optional.

Passwords crossing the network in readable form are a separate risk, covered in email settings that send passwords in plain text.


Frequently asked questions

How can I tell how my site stores passwords?

Click forgotten password on your own site. If it emails back the password you chose rather than a reset link, the system keeps passwords in a form it can read.

What is wrong with encrypted passwords?

Encryption is designed to be reversed, and the key usually sits in the same code. Anyone who copies the site and database often gets both, and with them every password.

How should a website store passwords?

As salted hashes made with a deliberately slow method such as bcrypt. The site keeps only the result of a one-way calculation and compares it at each login.

Why does it matter for a small site?

Because members reuse passwords. A copied list of email addresses and passwords is tried automatically on webmail, shops and banks, so the harm reaches far beyond your site.

Do members need new passwords after the fix?

Yes. Conversion protects passwords from now on, but they sat readable for years, in backups and exports too. Ask members to reset through the site rather than an emailed link.

Does WordPress store passwords safely?

WordPress hashes and salts its own user passwords. The risk usually lies in separate booking, membership or client systems that keep their own list of logins.

West Coast Media Solutions Inc. provides web design, web development, hosting, digital marketing, and business consulting to organisations across Canada, drawing on more than twenty-five years in the field.

Members area built years ago?

Ask us to check how it stores passwords. We will tell you plainly what fixing it involves.

Start a Conversation