How do I migrate to hashed Firebase passwords? - firebase

I have an existing client, which calls a server, which in turn calls
https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword
With that, client POSTs to the server (and server, to Firebase) an unhashed password over HTTPS.
I would like to salt/hash the password on the client. I am at liberty to use the same algorithm Firebase uses. But I don't see a method for sending a hashed password to Firebase. And I have existing users who, of course, can't lose access with this migration.

To sign in to Firebase Authentication's email/password provider, you have to send the password in cleartext over a secure connection. There is no way to change this.
This is not a security risk to send the password in cleartext, as the secure connection is end-to-end encrypted, so the only two sides who can see the data can already access it anyway. If somebody can intercept the data and decrypt it, it means they have access to the certificate of your secure connection, which is a much broader security risk.
Of you want to sign in with a password in a different form, the only way to do that is by implementing your own custom provider on top of Firebase Authentication.

Related

Where to start encrypting a user password?

I have an issue when it comes to encrypting user passwords. I have a authorization services with which one can create a user account. Given is an email and a password. As for now I encrypt the user password in the server before persisting it in the database.
However I feel that is somewhat wrong because the password is in plaintext when coming in through a https request. So I actually could log the real passwords of users.
Isn't that a dangerous way to handle user passwords? I think it would be better to encrypt user passwords in the client side code (javascript) before submitting a form (either registration or login). So the password will arrive encrypted already.
Am I right with my concerns?
I encrypt the user password in the server before persisting it in the database.
Please don't. Use slow salted hash if possible (BCrypt, SCrypt, Argon2,..)
If you really cannot use the mentioned functions, than a database native hashing functionality is better than encryption.
https://practice-code.github.io/architecture/how-to-store-passwords-in-a-secure-way/
the password is in plaintext when coming in through a https request
Nope, the https encrypts traffic between the client (browser) and the server.
Yes you can see the password in the browser side before encryption (but the user entered the password, so it looks ok to access its own data) and the server needs to validate the password anyway.
Isn't that a dangerous way to handle user passwords?
Indeed. So maybe it's a good idea to offload the user authentication to already proven services (AWS Cognito, IBM AppID, Azure AD,..) or to social accounts (Google, FB,..)
I think it would be better to encrypt user passwords in the client side code
As already commented, that is not helping at all. Then the encrypted value becomes the password
Nothing is in clear text when using HTTPS, data is encrypted that is the main point of using server certificate !
As an alternative approach usually one stores the password hash in db instead of the password text, so eventually your code uses hash algorithm to generate the password hash and compare it versus one stored in DB, by that even if someone was able to access the database records ,that one is unable to figure out what is the password because all he gets is the hash value
Using Hash in C#

Should I pass encrypted data in a JWT token?

We are implementing JWT to allow our client side to authenticate through our separate authentication server.
The client posts the username and password to the authentication server, receives a JWT and then logs in to the main site with the JWT.
Clearly, the token includes the username and some other non-secret information.
The question is if to use JWT to pass secret information and how.
Here are a few options that might be considered:
Don't do it. Have the main website server call a back-end API with the authenticated username to get the information it needs.
Pass the information as Private claims encrypting the values with a symmetric encryption and sharing the key/pass-phrase between the main website and the authentication server.
Encrypt the entire token.
Are there any best practices here? what are the ups and downs of these options?
You shouldn't use JWT for passing secret information.
These tokens are usually signed to protect against manipulation (not encrypted) so the data in the claims can be easily decoded and read.
If you need to pass sensitive information please look at JSON Web Encryption(JWE)
You should check JSON Web Encryption for this purpose

Web API BasicHttpAuth with hashed password

So I have a web Api that authenticates users by username and password. The clients talking to the API will android phones that have an internal app on it to get / send some data from / too the api.
I have hashed passwords in the database with a salt. The connection between the client and the API will be SSL.
Now on the website (MVC) I log users in by generating a new hash and matching this against the hash in the database.
The some of the android devices will have a config file that locks the app to a specific user. Now I rather not store the password in plain text on the device and would like to encrypt the password.
The question now is what would be the best practise here on comparing the hashed password. I dont think its save to just send the plain password to the API or is it?
It's safe, because you're using SSL.
Basic authentication isn't acceptable for plain-text requests, but since HTTPS encrypts everything, it shouldn't be an issue.
Storing the password is a completely separate concern, as you've noted, and that should be encrypted as well, which it sounds like you'll have Android do for you. The only consideration is that you will have to do a reversible encryption to be able to send up the password itself to your API.
Basically:
(client-side) User enters creds
(client-side) Encrypt creds, store in configuration
(client-side) Read from config, decrypt creds
(client-side) File HTTPS request to API with Basic authentication type, using decrypted creds
(server-side) Hash (one-way encrypt, basically) the password, compare against database
That sounds like exactly what you've got, and I see no problem with it.
That all said, just for what it's worth, I'd be tempted to implement an OAuth 2.0 server for this particular use-case, so you don't have to think about persisting the password at all. That's a pretty big undertaking (sort of--it doesn't take too long with those instructions), and you should evaluate it on a case-by-case basis. But any time I have to worry about API authentication, I generally wind up either going with that, or wishing I had.
I would consider using something like JWT (JSON Web Token, http://jwt.io). You can have a client authenticate against your API, and if they provide the right credentials you can issue a token to them, which they can persist on local storage. They would then provide this token in the header of any API requests that require authentication. You can use OWIN middleware to intercept requests, check/validate the token and let the requests through to your controllers if you consider the token to be valid.

Encryption of password while logging in

When we log in to a website like Gmail we give our password , Now Gmail is a Https website hence during transit, the password cannot be sniffed by Man in the middle attack ,If there is a SSL MITM ,then the password is seen in cleartext.
Is there a mechanism ,which encrypts the password during log in i.e even after SSL MITM the attacker would only get the encrypted password.
This would be client side functionality using javascripts , right?
But again the client can choose to prevent or modify the scripts.
Or is there any other mechanism?
You could hash your username and password at the browser/server and then compare hashes at the business layer. This will prevent MITM attacks and allow the BO to validate credentials.
You could use Javascript, but then you (1) have to get the Javascript safely to the user and (2) exchange keys to do the encryption.
While there is some value in protecting the password, if the SSL session is compromised the MITM can hijack the session and all the data, or prompt the user to change their password and just collect it.
You could use OpenId, but then you only move the problem of authentication to the OpenId server. You still need a way to get the user's secret to the server.
So, generally, clear-text passwords over SSL to establish a new, authenticated, session cookie is the way to go. Anything else reduces down to your orignal shared secret problem or the web browser not having anything but SSL to work with.

Is basic access authentication secure?

Using Apache, it is quite simple to set up a page that uses basic access authentication to prompt a user for a name/password and use those credentials in some way to grant access to that user.
Is this secure, assuming the connection between the client and server is secure?
The worry about basic auth is that the credentials are sent as cleartext and are vulnerable to packet sniffing, if that connection is secured using TLS/SSL then it is as secure as other methods that use encryption.
This is an old thread, and I do not believe the highest voted/chosen answer is correct.
As noted by #Nateowami, the security stack exchange thread outlines a number of issues with basic authentication.
I'd like to point out another one: if you are doing your password verification correctly, then basic authentication makes your server more vulnerable to denial of service. Why? In the old days, it was common belief that salted hash was sufficient for password verification. That is no longer the case. Nowadays, we say that you need to have slow functions to prevent brute forcing passwords in the event that the database becomes exposed (which happens all too often). If you are using basic auth, then you are forcing your server to do these slow computations on every API call, which adds a heavy burden to your server. You are making it more vulnerable to DoS simply by using this dated authentication mechanism.
More generally, passwords are higher value than sessions: compromise of a user password allows hijacking the user's account indefinitely, not to mention the possibility of hijacking other systems that the user accesses due to password reuse; whereas a a user session is time-limited and confined to a single system. Therefore, as a matter of defense in depth, high value data like passwords should not be used repeatedly if not necessary. Basic authentication is a dated technology and should be deprecated.
The reason why most sites prefer OAuth over Basic Auth is that Basic Auth requires users to enter their password in a 3rd party app. This 3rd party app has to store the password in cleartext. The only way to revoke access is for the user to change their password. This, however, would revoke access for all 3rd party apps. So you can see what's the problem here.
On the other hand, OAuth requires a web frame. A user enters their login information at the login page of this particular site itself. The site then generates an access token which the app can use to authenticate itself in the future. Pros:
an access token can be revoked
the 3rd-party app can not see the user's password
an access token can be granted particular permissions (whereas basic auth treats every consumer equally).
if a 3rd-party app turns out to be insecure, the service provider can decide to revoke all access tokens generated for that particular app.
Basic auth over http in an environment that can be sniffed is like no auth, because the password can be easily reversed and then re-used. In response to the snarky comment above about credit cards over ssl being "a bit" more secure, the problem is that basic authentication is used over and over again over the same channel. If you compromise the password once, you compromise the security of every transaction over that channel, not just a single data attribute.
If you knew that you would be passing the same credit card number over a web session over and over, i'd hope that you'd come up with some other control besides just relying on SSL, because chances are that a credit card number used that frequently will be compromised... eventually.
If you are generating passwords with htpasswd consider switching to htdigest.
Digest authentication is secure even over unencrypted connections and its just as easy to set up. Sure, basic authentication is ok when you are going over ssl, but why take the chance when you could just as easily use digest authentication?
As the name itself implies, 'Basic Authentication' is just basic security mechanism. Don't rely on it to provide you with worry free security.
Using SSL on top of it does makes it bit more secure but there are better mechanisms.

Resources