Clientside password feedback
Change summary
I've implemented async loading of zxcvbn.js so password feedback can already happen interactively clientside.
Demo
https://github.com/user-attachments/assets/c94a8af4-f0a3-4795-b352-34653639a125
Details
The zxcvbn lib I've downloaded from here as I didn't understand if you have a js package manager workflow: https://raw.githubusercontent.com/dropbox/zxcvbn/67c4ece9efc40c9d0a1d7d995b2b22a91be500c2/dist/zxcvbn.js
The lib will be loaded as <script async> so not to delay page load, and until it's loaded, client-side feedback on the password will not happen. (only check if repeat box has same content)
- [x] This PR contains no AI generated code
- [ ] ~~book chapter included (if relevant)~~
- [ ] ~~design document included (if relevant)~~
I won't support adding an 800KB client-side dependency for this, since we also do additional checks server-side.
It's not a dependency - it's loaded in the background asynchronously, so it doesn't delay loading the page. The password form is usable without it, just doesn't give feedback until the lib is loaded.
We could also use a smaller wordlist for clientside - but that would make it inconsistent with the serverside check.
I think the UX for choosing a password, repeating it, submitting form - and only then seeing feedback is quite bad (and having to re-type both passwords and submit for a new attempt). It's well worth loading something in the background in my opinion.
I think the issue here is that we want there to be "one place where this is checked". The worst case would be that the client side rejects a password that the cli accepts, or that the server rejects a password that the client said was acceptable. We have to make trades here, and I think that server-side checking gives us the most reliable method for ensuring that the experience is ultimately consistent. There are possibly ways we can check this or expose this validate api in a better way, but I'm not sure clientside feedback generation is what we want to do here.
The other thing about doing this server side, is we then have an api that other things can use (like the cli) which also needs to have this feedback too.
Like another option could be to have a "delay" that when typing stops for some small time, we can submit the pw for check to an end point to get the feedback. That way we can get the feedback faster (solving your use case) but also ours (single source of truth).
@Firstyear The server should never see your plain text password though.
@Firstyear The server should never see your plain text password though.
In our case, it should. The server is the one keeping track of the password π This is one of the many reasons we have strong opinions about TLS π
@Firstyear The server should never see your plain text password though.
In our case, it should. The server is the one keeping track of the password π This is one of the many reasons we have strong opinions about TLS π
On the server, you should be using password hashing, no? Like Argon2id.
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html https://appwrite.io/blog/post/goodbye-plaintext-passwords
@Firstyear The server should never see your plain text password though.
In our case, it should. The server is the one keeping track of the password π This is one of the many reasons we have strong opinions about TLS π
On the server, you should be using password hashing, no? Like Argon2id.
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html https://appwrite.io/blog/post/goodbye-plaintext-passwords
It is STORING the password in hashed form.
@yaleman True. Can you use OPAQUE here?
@yaleman True. Can you use OPAQUE here?
No, and please keep discussions specifically related to the PR and its changes π
@yaleman True. Can you use OPAQUE here?
No because then we never see the password so we can't enforce strength rules on it. OPAQUE is a PAKE (Password Authenticated Key Exchange) which means that even though we won't see the password, and it "shouldn't" be possible to attack if disclosed from the server, we only get client side validation of the password complexity, and thus open ourselves to new attacks.
Yeah it's a good point that JS implementation is probably different sometimes (also mentioned in ZXcvbn paper as non-goal to have parity).
So what do you prefer: server API or compiling zxcvbn-rs to wasm and load in the client? π€ It's officially supported: https://github.com/shssoichiro/zxcvbn-rs/blob/master/.github%2Fworkflows%2Fzxcvbn.yml#L70
Server API is the requirement. ZXCVBN isnβt the only check thatβs done, see also credential deny listing
Yeah if I get time I want to add this api soon.
As a reminder https://github.com/kanidm/kanidm/pull/3847 is now done if you want to update the PR.