For developers: you must not require needs passwords from users
Tags: security, webdev, architecture, web
Published: 2024-05-03 08:58:32

Firstly let's glance at what we have today

Today many websites require a password
- They require "a good" password:
 - minimum N letters
 - at least one should be in the uppercase – and users do it with the first letter
 - at least one special char – and users add the exclamation point (!) at the end of its password
 - at least one number – and users add the number one (1) at the end of their password
 - it is not my own opinion, just check the research of [Princeton Password policies of most top websites fail to follow best practices](https://passwordpolicies.cs.princeton.edu/)
 - And more – requirements like this are outdated now, just read the [NIST 800 63b](https://pages.nist.gov/800-63-3/sp800-63b.html)
- Users use their favorite password for all websites, but because some websites have their own requirements – users use only variations of the one password
- Websites  do not notify users about possible leaked passwords
 - But they can use a free API of [haveibeenpwned](https://haveibeenpwned.com/Passwords) to check possible data breaches (it's a secure API, you should not pass the users' passwords, because there is used protocol [k-Anonymity](https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/#cloudflareprivacyandkanonymity) – passing only the first 5 letters of SHA1-hash of the password)
- Applications do not store passwords securely, let's review the correct way: 
 - Firstly – use only a special algorithm for hashing a password, for example, Argon2id, scrypt, bcrypt, or PBKDF2 (my choice)
 - Add salt, that stores not in the database and not in the code; because if the database leaks – application salt should not leak
 - Add a UserId to the salt – if two users have the same passwords their hashes will be different
 - Use a GUID as a UserId – it's difficult for guess
 - The selected algorithm should have the right settings, for example, the PBKDF2 requires at least 600_000 iterations – complicates brute forcing hashes
 - Read more in the [Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)
- Also, applications do not use rate limits / throttling / invisible Recaptcha mechanisms to protect users from brute forcing by your API
- Applications with passwords must provide the possibility for password resetting, and sometimes they do that incorrectly (just read [Forgot Password Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html))
- Finally – many users do not type your website address in the address bar of their browsers, they just google your solutions by the company name
 - this way is very phishable because today [hackers just pay Google Ads](https://searchengineland.com/google-search-ads-brands-fraud-436871) for a concrete city to catch victims (who google) and redirect them to its phishing recourse (that could be created by [gophish](https://getgophish.com/) easily)
 - many applications provide session cookies with a long expiration period, which is why a lot of users do not know what password was used (6 months ago) on your website, if they bought a new laptop, or when they lost a session

So my main points:
- Passwords are too complicated to implement a good solution, that provides a real protection
- And it's complicated for use by users (of course not for all, but for typical user of typical bookstore...)
- Many websites provide resetting passwords only by a short code to a user's email address
- That is why I have to say: many websites should forget about password usage forever, and they must start using magic links

Magic links must:
- contains a long one-time token that will be exchanged for a permanent session token
- this token works only for an IP address and a user agent, which were used for the first sign-in step – entering the user's email address

Two items, That's all!

- Now users are protected against typical phishing attacks
- If your database leaks – there won't be any passwords
- You spend less time to supporting a password workflow
- For users, who always use their favorite passwords or forget their passwords – it will be the same as a password resetting flow

PS:
- as an alternative – these websites may use sign-in/sign-up processes only by SSO, but again – [they must know the best practices here too](https://portswigger.net/web-security/oauth)
- of course the best way – [using passkeys](https://webauthn.me/), but I'm not sure, that all new developers (and users) are ready for it now, I'll write about it later
- for finance it's difficult to live without passwords, because they must [comply to SCA](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32018R0389#:~:text=In%20order%20to%20ensure%20the,and%20in%20the%20authentication%20process.
), but they can start to use passkeys, and it is yet another story...

PPS: I have very good experience with good implementations and with failures on many different online solutions (sometimes as a developer, sometimes as a pentester), so please write down your concerns

Bonus if you have read that – try the password game https://neal.fun/password-game/