Customer passwords in PrestaShop: how they are stored and what not to do
PrestaShop does not store your customers' passwords; it stores a digest that cannot be reversed. We explain how it works in each version, what happens when you migrate customers and which practices turn a technical detail into a data leak.
A customer calls because they cannot remember their password and asks you to tell them what it is. You cannot, and it is a good thing that you cannot: the shop does not know it. What PrestaShop stores in the database is not the password but a digest calculated from it, which cannot be turned back into the original. Understanding how that digest works saves you mistakes when migrating customers, importing accounts and providing support.
What the shop actually stores
When a customer creates an account, PrestaShop runs the password through a hash function: a calculation that turns a piece of text into a fixed-length string. The same password always gives a verifiable result, but the password cannot be recovered from the result. At login, the shop recalculates the hash of what the customer types and compares it with the stored one. If they match, the customer is in.
The hash lives in the passwd column of the customer table (ps_customer with the usual prefix) and, for employees, in ps_employee. Seeing that column does not give anyone the password, but it does let them try candidate passwords away from your server, with no limit on attempts. That is why the algorithm used matters so much.
How it has changed from version to version
PrestaShop 1.6 and earlier
The hash was an MD5 of the password concatenated with the installation's cookie key. MD5 is extremely fast to compute, and what is a virtue in other contexts is a flaw here: an ordinary computer can test huge numbers of candidates per second. If someone gets hold of the database and the cookie key from the configuration file, weak passwords fall almost immediately.
PrestaShop 1.7, 8 and 9
Since 1.7, PrestaShop uses bcrypt through PHP's password functions. Bcrypt is deliberately slow and uses a different salt for each user, so guessing passwords becomes far more expensive. The shop can still verify the old hashes: when a customer with a 1.6 hash logs in successfully, PrestaShop recalculates it with the new algorithm and saves it. Customers who never come back keep the old hash.
From PrestaShop 8 onwards you also have a configurable password policy in the shop's security settings (minimum length and required strength), which applies to new passwords.
Migrating customers from another platform
When moving from WooCommerce, Magento, Shopify or another PrestaShop, the question is always the same: will customers be able to log in with their password? It depends on the hash format at the source:
- If the source uses standard bcrypt, the hash is usually compatible and copying it is enough, provided you test it first with several real accounts on the staging copy.
- If it uses its own format (hashes with platform-specific prefixes, several rounds of another algorithm), PrestaShop will not be able to verify it. The options are a bridge module that validates the old format at the first login and converts it, or asking every customer to reset their password.
- If the source does not give you the hashes (some closed platforms do not export them), a reset is the only option.
If you are going to force a reset, prepare it: an email explaining the change of shop, sent in batches from a mail server that does not end up in spam, and a recovery page that works on mobile. Many customers will arrive from an order email rather than from that notice.
Resetting passwords without opening holes
The right flow is the one PrestaShop ships with: the customer requests recovery, receives a link with a single-use code that expires, and chooses a new password. Mistakes appear when people try to take shortcuts:
- Setting a password yourself and reading it out over the phone or sending it by email. It ends up written down in places you do not control, and the customer rarely changes it.
- Using the same password for everyone in an import («Shop2024» for every migrated customer). It is the first one anyone will try.
- Sending passwords in plain text in the welcome email. Some old modules do this. Check the email templates and remove that variable.
- Asking the customer for their password so you can log into their account and see what is wrong. If you need to see what they see, there are ways to do it without it.
What never to do
- Store passwords in plain text or with reversible encryption «just in case», in a custom table, a CSV or a notes field. A third-party module that does this turns any leak into a disaster.
- Export the full customer table to send to an agency or a supplier. Export only the columns they need, and never
passwd. - Leave database dumps in a public folder on the server. A
.sqlfile in the root contains every hash and the key to attack them. - Use the same cookie key on the staging copy and in production and leave the copy reachable from the Internet without a password.
- Write the contents of login forms to debug logs. It happens more often than you would think with modules in debug mode.
If you suspect they have leaked
If someone has had access to the database, act as if the hashes are out there:
- Close the way in first: vulnerable module, FTP or control panel credentials, public dump.
- Change the database password and those of all employees.
- Assess with a professional whether you need to notify the breach to the data protection authority and to those affected. The GDPR requires you to assess the risk and, depending on the case, to notify.
- Invite customers to change their password, especially if they reuse it on other services. If the hash was from 1.6, the recommendation is more urgent.
Why updating also protects passwords
A shop still on 1.6 stores passwords weakly, and will keep doing so until it is migrated. On top of that, the breaches that expose the database almost always come through modules that have not been updated. Keeping PrestaShop, PHP and modules up to date is not just about new features: it decides how much damage a leak does when it happens.
How to solve it in PrestaShop
RKR Security Alert does not manage passwords, but it watches what usually comes before a leak. Its audit warns you about .sql or .zip backups accessible in the root, configuration files with loose permissions that expose the database credentials, development mode and display_errors enabled in production, and inactive administrator accounts. It also detects new employees and changes to employees even when they are made by direct SQL, back-office logins from new IP addresses and web shells in the files, and it alerts you via Telegram without sending any file off the server.