How to store passwords safely on a device? - security

I have a raspberry pi that needs to access a service using a username and password. What is the standard procedure to store the user credentials on the device.
I know that a user on a phone would enter the username and password in order to get a token which is valid for a certain period of time. This allows to !not! store the credentials locally.
However, my device (DVR) needs to run 24/7 and the user cannot regularly enter the password. So I somehow need to store the password on the device to login every once in a while or after a reboot.
I am concerned because the device is publicly accessible and someone could potentially take it, plug it into a computer and read the password from storage.

You have to think about what exact attacks you want to protect against. The TL;DR is you won't be able to protect it against everything that comes to mind.
One question is whether it's ok to enter some kind of a secret (a password) when the device boots up. You're saying it's running 24/7, so a reboot should probably not be very frequent. If your concern is somebody taking the Raspberry and reading the password from the disk (or card, in case of a Pi), you could try and keep it in memory only. Startup would need the password to be entered, but whoever takes the device (or the card) physically would not be able to learn the password. Of course this is not entirely secure, somebody could either read the password from memory without taking the Pi (you said they have physical access), or they could maintain power while taking it so that the password is kept in memory. But it would be much more secure than writing the password to the storage.
Another thing you can do is assign the device some kind of a token. If you think the token is compromised (somebody learnt it in any way), you can just change the token to a new one. But you still need a way to discover when credentials are stolen. But you would need this anyway.
You can monitor the device for physical tampering or theft. If it is tampered with or stolen, you can assume the credentials are compromised, and you can then issue new credentials to your service.
Also you're saying it runs 24/7, so I assume it has a fixed IP address. You can implement IP address restriction on the service that it connects to with the credentials, so even if credentials are compromised, an attacker is very limited in where he can connect from (but you mentioned a DVR, which typically uses UDP traffic, and it's much easier to forge source IP addresses over UDP than over TCP).
Probably needless to say, but obviously you should use unique credentials on this device that you use nowhere else and for no other puspose.
Note that you can pick several of these if you like to protect against different threats, or to build defense in depth. But you have to keep in mind that whatever you give to users (potential attackers) is lost and you can safely assume they have full control. However, the level of effort is different, and if you can make it hard or risky enough for an attacker, that's probably reasonably good in many situations.

Related

How to reliably detect if a user is connecting to a site with a new device?

I have a requirement where an email (or SMS) verification to be obtained whenever a registered user logs into a site using a new device/browser, similar to what Salesforce is doing.
Goal is to reduce the chance of user account being misused by someone, but at the same time it should not become an nuisance to the users.
What are the reliable mechanisms to detect if a request is coming from a new device?
One way would be to use the IPAddress, but that would cause issues when someone's internet connection gets a dynamic IP, and with mobile devices which will get new IPs as they move to new places.
Has the advantage of all browsers on that device (FF/Chrome/IE) are authorized with single confirmation.
Other way is to use a persistent cookie (without sliding expiration), downside is confirmation will have to be repeated for different browsers. (Not a huge issue though, as it's unlikely scenario).
Third option is some kind of hybrid solution of the above two.
My question is, are there accepted mechanisms to do this? What are the reliable ways to detect if someone is using a new device to connect to the site (doesn't have to be bullet-proof though)? Any other advice?
I'd go with the Cookie.
IP addresses are often shared. There's not really a way to identify their computer other than via the browser on the web.
The cookie value should include the username and an HMAC of the username (and probably a nonce too).
After user registers or logs in successfully, send the device cookie. If they are trying to login without a device cookie, they probably haven't used that browser before.

Let an app sign documents, but don't let it see the keys

I want to digitally sign documents and messages on a Linux server. How do I securely store the private key and a passphrase if any?
The problem is, if an application gets compromised, keys would also become compromised. If I could somehow let an app sign something, but don't let it touch actual keys, that wouldn't completely solve my problem (as an attacker would still be able to sign anything for some time), but reduce the impact (like, we won't have to revoke the keys).
For example, in case of SSL servers there's no such problem because usually there's no practical need for an application to access the keys. Hence, they can be semi-securely stored in a separate location. E.g. a webserver (like nginx) would be able to read the keys, but not the application.
Am I overthinking it? Is it even worthy thinking of?
Create a separate, lightweight signing application that listens on an UNIX socket and runs as a separate user from the main app; when your app wants to sign something it throws the file and any additional info down that socket, and gets back the signed file.
If the application ever gets compromised the attacker will still be able to sign files as long as he is still on the server, but unless he uses a privilege escalation exploit to get root privileges and copy the signing app's key, he won't he able to steal the key and then sign at will without being connected to the server.
You can replace the UNIX socket with a standard TCP socket and put the signing app on a separate server for extra security; make sure to implement some basic access control on the signing app and of course use proper firewall rules to make sure the signing server is never exposed to the internet, or simplify things a bit by using a "setuid" binary for signing that gets invoked by your app, in that case the signing binary will run as a different user with additional privileges to access the keys, while the webapp itself doesn't have such privileges.
Basically you should implement a rudimentary software HSM.
If you have very high security needs you could consider moving the keys to a completely independent server, or better yet a hardware security module (but those are expensive). Like you mention it can help prevent the loss of keys, but if the app is compromised the attacker could still sign whatever they wanted.
The main reason to go through the trouble then is auditing. That is if you have your signing server or device keep logs of everything it signs, then if only your app is compromised you will be better able to assess the extent of the damage (assuming you're signing server has not been compromised).
So yes there are benefits, but your first focus should be on securing your main application properly, because once that's compromised you're already having a very bad no good day, even if you have moved your keys to a sperate service.

Securing a login system without passwords

I'm developing a mobile application for a company. Everyone at the company has an #company.com email address. The app itself is confidential, so it will only be installed on employees' devices. This app communicates with an external server to store and retrieve data.
Ideally what I would like to accomplish is to let people log in to the app by just providing their email address, without a password. Here is my current thinking:
A new user opens the app for the first time on a certain device and puts in their email address. The email address is sent to the server, along with a static token embedded in the application (which is the same for all instances of the application).
The server verifies the token and the fact that the email address is #company.com. It responds with a new token/key for use only with that user and device, which the client stores in plain text locally. That key is effectively the user's password. It is hashed, stored in the server database, and marked as disabled.
There are two possibilities at this point:
The server sends an email to that address confirming that they want to log in on a new device. The email contains a link which, when clicked, marks the key as enabled. There would need to be rate-limiting on new device requests so people can't get spammed if someone discovers the token embedded in the app.
An administrator specifically approves new device requests.
Every subsequent client request to the server must include the key.
Assuming all communication is over SSL, does this sound like a secure strategy? Is there a more secure or simpler approach?
Additionally, what is the best way to generate the token that will be stored client-side? Since I want users to only put in their email address the first time they use the app, I believe that this token will never change. Here is my current algorithm (PHP) loosely based on Drupal's drupal_get_token():
// Usage: get_token($email) or get_token($client_token)
function get_token($value = '') {
$salt = hash('sha256', 'Some static, predefined phrase');
$hmac = base64_encode(hash_hmac('sha256', $email, $salt, TRUE));
return $hmac;
}
As you can see it doesn't protect against parallel attacks (e.g. if someone figured out the predefined phrase and algorithm and they had access to the database, they could generate hashes and compare them against the ones stored in the database) but because the original key value is already long I don't think this would be nearly as effective as it would be against normal passwords. Additionally I am not sure of a way to create a dynamic salt that an attacker would not already have access to if they could access the database (or honestly if it would even matter at that point, since getting access to the database would expose the data we're trying to keep confidential anyway).
After some research and more thought, I believe that the answer to this question comes down to the vulnerability of the local storage. Since it's safe to assume in this case that only company employees will be using the app, there is insignificant risk of malicious code running in it even if there was a problem in the code that would make that possible. As a result the main risk is from some other app taking advantage of a security hole in the OS's local storage implementation to read the local private key off the disk. Since the existence of the app should not be known to anyone outside the company, it is very unlikely that this information would be directly targeted. So I think this is an acceptable process for this company.
In the general case though, anyone considering implementing a similar model should be aware of the risks of basically storing a password in plain text locally. (This is as opposed to storing a password in the user's head, or equally likely in plain text in a password file elsewhere on their machine; it's your call which is more secure.)

Which one method is safer: save password in device or use token?

We are making an app on android and iphone. One method is to save password hash in local device and login remote server every time (with token). The other method is to login once and then get the token to communicate with server. The app save the token in device, so if user don't logout manually, the token won't expire.
Some teammates think the latter method is better instead of saving password hash in local device. But I think keep token is also unsafe. Could anyone please give us some suggestion?
We probably need a little more detail to evaluate what you're considering. Either could in theory be built well. There are several things to consider.
First, it is best to have your authentication token expire periodically. This closes the window on stolen tokens.
Authentication should always be challenge/response in order to avoid replay attacks. You should generally not send the token itself. You send the response to a challenge that proves you have it.
Of course you start with TLS as a transport layer. Ideally you should validate your certs. Together, this alone can protect against a wide variety of attacks. Not all attacks; TLS is not magic security dust, but it does provide a very nice "belt and suspenders" defense in depth.
It's interesting that you're saving the "password hash." How are you using this and how are you salting it? In particular, if many people have the password "password1", will all of them have the same hash? Without TLS, this can open you up to significant problems if you're sending the hash itself across the wire.
On iPhone, you should store sensitive credentials in the keychain. SFHFkeychainutils makes a decent wrapper around the keychain (I've got my beef with it, but it's ok). Unfortunately, I don't believe Android has a similar OS-provided credential store. (No, iPhone's keychain does not protect against all kinds of attacks, but it does provide useful protections against certain kinds of attacks and is worth using.)
You want your protocol to make it possible to deauthenticate a device that has been stolen. That could take the form of the user changing the password, or revoking a token, but the user needs a way to achieve this.
Again, it's hard to evaluate a broad, hypothetical security approach. Tokens or passwords in the protocol can each be fine. What matters is the rest of the protocol.
The way to analyze this is to assume that nothing on the device is safe. The question then becomes, what's the worst that can happen if (when) the device is compromised. If you save a token, then the user's credentials are safe and you can implement a method on the server of revoking a token. If you save a password hash, then (if I understand what you mean by this) the user will need to change passwords (and possibly a token needs to be revoked).
Also, if you tie the token to some sort of device identifier, then it would be harder to use the token from other devices. A password hash (unless it also included data about the device) would not be as hard to use on other devices. (These attacks would be available between the time the device was compromised and when corrective action was taken at the server.)
As you might guess, I agree with your colleagues about which of these two approaches is better. (I also should make clear that I don't think either of these is the most robust approach. You might want to do a little research -- search for mobile application security to find a lot of information about different approaches.)

Secure authentication on a device occasionally without connection to a server

I am working on a server application which will have quite a fair number of client devices accessing it.
The problem is we cannot guarantee that the client devices will always have access to the server. It is perfectly possible for a device to be outside the network for 1 week or more. In the meantime, we still want the device to work in an autonomous manner with a copy of the necessary content (automatically updated when connected to the network).
Of course, this is causing some security issues related to the user authentication. We plan to have the device have a copy of the users list. We are pondering on how to have the authentication secured on the device. Obviously we cannot send the passwords in plain text in the update packages.
Passwords on the main server are salted and hashed and we are thinking of using a hash of some sort (SHA1 ?), for the list available to the client device.
By doing so however we are lowering the bar for attacks on the devices (no salt).
Would you have any suggestion for an efficient way to keep the client devices as secure as possible?
Thanks!
First of all, you need to be clear who the attacker is. In this case, what if someone where to steal the device? Another scenario is what if someone where to connect to the server with a malicious client? What if someone where to sniff the traffic?
To stop sniffing all communication should be done over ssl (probably https). To prevent malicious clients you can identify each client device by a SSL certificate hardcoded and store these credentials on the server side in a database. The server could use a normal certificate from a CA. If a device is stolen you could revoke the certificate in your local db. A full PKI isn't necessary, although this is a case where one could be used with great results.
Spilling the password hashes to the attacker(client) is always a vulnerability. Transferring all of the password hashes to the client is commonly done with sql injection. This is not a solution.
md5 is broken in many different ways and exploited in real world attacks. sha1 is more secure and still approved by NIST, however sha256 is a very good choice. Salting password hashes with a random value is necessary.
A secure solution that I can think of for your password problem is to only allow authentication while connected to a network. That user could be cached and then that user could log out and log back in. This limits the attack scenario but doesn't negate it. If someone where to steal the device he would also have a password hash, in this case the user must be forced to change his password (and hopefully this happens before the attacker has a chance to break the hash).
A less secure solution would be to use a heavy hash function such as PBKDF2. This is used in applications like winzip where the password hash is always available to the attacker. The drawback is its EXTREMELY SLOW and can't be used for normal web applications because of this.
If you don't have a good reason to weaken passwords on client device, use the same auth scheme on client and server. Client devices can handle salt too.

Resources