V Sat, Jun 25, 2022 at 07:12:43PM +0300, Isaac Boukris via curl-library napsal(a): > Problem statement: > While there are many problems with password authentication, the main > problem I try to alleviate is password reuse across different sites, > which most people do (in the best case with some minor differences). > As we know from history, you can't trust servers to only ask for and > save the password hashes with salt, and even if the server complies > with that, it could still get compromised and then the attacker could > simply change the web page to prompt for the password in clear. > > The current solution pushed by the big tech companies is to drop the > use of passwords, and instead use PKI, certificates etc (see > WebAuthn). While this is better in most cases, I don't see it > happening in practice, and it does have some drawbacks, e.g. private > keys are just long passwords in a way, which normal humans cannot > remember and so have to be stored on a device, which you then have to > physically protect. > > Proposed improvement: > The idea is to add a new HTTP authentication scheme, where the browser > will make sure the prompt to enter the password has a distinguish UI > which cannot be faked with javascript or anything, Then the browser > sends the hash of the entered password concatenated with the server's > certificate (thus can only work over TLS), and so the requirement from > the user would be, to only ever enter his password in this special UI > (or with curl, using a special argument option). > > Here's a suggested flow to register a new password and how to update > it upon server certificate change: > - the user submits his registration details except for the password. > - the server replies with "401 www-authenticate tls-bound-pwd". > - the browser prompts the new secure password UI and the user enters > the password, the browser then calculates "HASH(password, > server-certificate)" and sends to the server in an "Authorization > tls-bound-pwd b64(hash)" header (where HASH could be the hash > algorithm used in the server certificate for instance).
This has a race when the server changes a certificate while having an open connection to the client. The client should return "Authorization tls-bound-pwd b64(certificate) b64(hash)". An established TLS connection usually does not need the certificate any more. HTTP is stateless in contrast to TLS. > - the server saves the user's password hash, along with the > certificate it had used at the time. Here the server should save a certificate the client sent him. > - next time when the client tries to access the site, the server > replies again with "401 www-authenticate tls-bound-pwd". > - the browser prompts again the secure password UI and sends the hash > to the server as before. The client again should send the certificate used for computing the hash. > - if the server certificate hasn't changed since, then the server is > able to verify the credentials. > - otherwise, if the server certificate has changed, the hash the > client sent using the current certificate won't match the one the > server expects, The server should first check wheter the certificates match. Then it can actually distinguish a changed certficate from a bad password and report to a client a different status code. > so in that case, the server sends back "401 > www-authenticate tls-bound-pwd b64(old-cert) b64(HASH(old-hash, > new-cert))" to prove to the client that it knows the old hashes so it > is fine to send them. > - the browser calculates the old-hash based on the old-cert, and if it > matches what the server sent, then the client sends again an > "Authorization tls-bound-pwd b64(old-hash) b64(new-hash)" header. Again the client should also send a certificate used for new-hash. > - the server verifies the old-hash and if it matches, it replaces it > with the new hash and the new certificate and successfully > authenticates the client. > > That is roughly the idea, I'd be glad to hear any thoughts and > feedback about it. > That's a good idea in general. However, as you can see the certificate entering the hashes can actually be replaced with a nonce randomly genereated by a client. Then there is no need too bind the authentication method to TLS. Actually I think that binding it to TLS would be a problem for servers which separate TLS and user authentication. E.g. you terminate TLS on a dedicated proxy and then route the decapsulated HTTP relation to an application (or session) server. in that case the application server does not have access to the certificate. I haven't search for various WWW-Authorization mechanisms, but I have a dim memories that someting like that already exists. -- Petr
signature.asc
Description: PGP signature
-- Unsubscribe: https://lists.haxx.se/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html
