Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a bad idea to send username and password with every request from a mobile/web app to the backend api

I feel that Is it a bad idea to send username and password with every https request from a mobile/web app to the backend api but i cant come up with too many good arguments for why.

In the server, we store the hash of the password in a user record. in any case, on each request we need to load this user record from the database, for example to check if the user was not just blacklisted. As we need to load on every request the user record, it's cost nothing to compare the passwords and in this way no need to manage another database of sessionID or tokens.

Also as the password is send in https connection, their is no way for someone in the middle to catch it. And even if someone in the middle could do it, then he can probably also do it when the user need to first login (because anyway he will need to send his password at the beginning)

So what is the good way to do ?

like image 404
zeus Avatar asked Jan 17 '18 16:01

zeus


1 Answers

This would make a great security interview question, because it measures very well the level of understanding in the security domain.

Sending username/password in each request is not advisable, but the other answer does not even touch on the real reasons why.

Technically, a username/password is pretty much the same as something like an API key, they are equivalent for the time they are valid. An API key is even worse in a sense, because depending on implementation, you would typically store API keys plaintext in the database, as opposed to properly hashed passwords (sidenote, but please use something like bcrypt or pbkdf2 when hashing). You are totally right, a password could be sent the same way as an API key on each request, you can revoke it the same way, etc. The API key is the password. There is absolutely no difference in this regard.

However, you should still probably not do it in most cases, for at least the following reasons.

Passwords are weak if chosen by users. If you have many users, many will have passwords like 123456 and similar. It will be easy to guess some of them. You don't need to run this risk in an API app, however, sending it in every request or not barely modifies this risk, but it does a little bit, because of the next point.

Sometimes there are weaknesses in SSL/TLS. It does happen from time to time that a new attack against TLS is disclosed, which is then patched eventually. For some time though, it may be possible for an attacker to deduce bits from an encrypted stream, which may be made easier if the encrypted content is partially known (ie. common passwords). Chances are not very high, but the problem is, with many TLS cipher suites, an attacker can record traffic now, and decrypt it later (because it takes long, or the method is not yet invented). If he only decrypts an API key that has been obsolete for 3 years, fine, but if it's a user password... Not so good.

Server vulnerabilities can also be a problem. A while ago there was a vulnerability in the openssl implementation where you could practically read parts of the server memory (the webserver process). If the webserver receives the user password all the time, it will be in memory probably multiple times. If it's just a temporary API key (or a session id or whatever), that's less value for the attacker. It's still good, but at least not the password.

Internal attackers are also something to consider. If you have an attacker already on the server, he may not be able to access the database to directly read/modify credentials, but he may be able to observe the web server process for a limited time. The same as above, it's much better if he can only observe temporary ids instead of actual passwords.

You need to store the password on the client if you want to send it with each request. Storing sensitive stuff on the client is not usually a good idea, opens up possibilities for an attacker. It's usually better if the user enters credentials, receives a temporary token and the client forgets about the actual password until the token expires and the user has to provide his password again. This of course may or may not be acceptable from a user experience point of view - but security is always a balance. :)

So as you can see, sending the username/password in each request is not a direct vulnerability. In fact, it may even be acceptible in many scenarios. But you can make it more secure by using temporary credentials, and why would you not, if the cost is reasonable?

like image 104
Gabor Lengyel Avatar answered Sep 27 '22 00:09

Gabor Lengyel