I am in a sticky situation where I am writing an application that sends out emails to clients using an email account of my company. The issue here is that I have to have the password for the account to make the mail service on the server send out emails from that account. I know that passwords should never be stored in plain text, particularly ones that are used for an important email account. The dilemma here is that the program NEEDS to have the actual plain text password to send the emails so it needs to be stored somewhere accessible by the program. The program uses a MySQL database to store information so there are three options in my mind:
1) Store the password in the program's memory, i.e. a private final String field.
2) A file on the on the server where the password can be read from
3) Somewhere in the MySQL database.
I would think that 1 is the safest option, but does anybody have ideas to handle this sort of situation to minimize risk of the password falling into the wrong hands? Thanks for your advice!
The comments pointing out that SMTP doesn't require authentication are correct. That said, all three of the options you specified are insecure, assuming that the server uses commodity hardware and software. I'll show why each is insecure, although I won't follow your original order.
2) A file on the on the server where the password can be read from
3) Somewhere in the MySQL database.
What if someone were to steal the server? Then, they could just open the file or the database, read the password, and immediately have access to all the important information in the company. So unless you have armed guards surrounding the server day and night, this is already pretty insecure.
But it gets worse. No computer system is completely invulnerable to attack, and several well-publicized attacks (Sony's PlayStation Network, for example) in the past few years have shown that an attacker can get to the contents of disk files and databases without physical access. Furthermore, it seems from your question that the server in question is meant to accept packets (HTTP requests, incoming emails, etc.) from the outside world, which boosts your attack surface.
1) Store the password in the program's memory, i.e. a private final String field.
This is tempting, but this is even more pernicious than option 2 or option 3. For one thing, a private final string field is stored in the .class file generated by the Java compiler, so with this option you are already storing the unencrypted password on the server's hard drive. After compromising the server as in option 2 or 3, an attacker can just run javap in order to get the plaintext password out of the .class file.
This approach broadens your attack surface even more, though. If the password is stored as part of the source code, suddenly it's available to all developers who are working on the code. Under the principle of least privilege, the developers shouldn't know extra passwords, and there's a very good reason here. If any of the developers' machines is stolen or compromised from outside, the attacker can look through the compromised machine's hard drive and get the plaintext password. Then there's source control. One of the really important benefits of source control is that it allows you to inspect any prior version of your code. So even if you switch to a secure method in the future, if the password has ever entered source control then the source control server is a potential attack point.
All of these factors add up to show that, even if the HTTP/mail server's security is top-notch, option 1 increases the attack surface so much that the HTTP/mail server's security doesn't really help.
Extra detail: At the beginning I specified "assuming that the server uses commodity hardware and software." If you aren't using commodity hardware and software, you can do things like boot from readonly storage and use only an encrypted database, requiring a person to provide the decryption key on every boot. After that, the decrypted information lives in memory only, and is never written to disk. This way, if the server is stolen, an attacker has to unplug the server and so loses all the decrypted information that was only ever in memory. This kinds of setup is sometimes used for a Kerberos KDC (with the server in a locked boxe for extra security), but is rarely used otherwise, and is frankly overkill when there is an easy way to solve your problem without going to all this extra expense.
If you were serious about keeping it safe, you could encode the password and put it in 2 or 3. When you need to use it, simply have your program decode it and save it in memory as a plain string.
ex.
String encodedUrl = URLEncoder.encode(url,"UTF-8");
String decodedUrl = URLDecoder.decode(url,"UTF-8");
This is a common problem. You can store the password in MYSQL in a blob field applying AES encryption on the insert; using and keeping the key_string in java for handy decryption.
MYSQL Syntax :
AES_ENCRYPT(str,key_str)
and
AES_DECRYPT(crypt_str,key_str)
The insert would be similar to the following:
INSERT INTO t VALUES (1,AES_ENCRYPT('password','encryption_key'));
You would use the key to decrypt coming out
SELECT AES_DECRYPT(password, 'encryption_key') AS unencrypted FROM t
So you never store the password as plain text in your application although you will need the encryption key. Your connection to the database should be secure. Logs may be an issue.
Alternately you could use stored procs to get the keys in and out or you could encrypt them server side and insert/retrieve after encrypted.
Related
One of my java class will connect to a another server and do some operation using rest services. Java class requires - username and password to connect to remote server. On other machines we used to store the credentials using oracle cwallet.sso but this is not an option for current machine. I am thinking to store the encrypted password in properties file adding some salt. I also need to store the key and salt string to some secure place. do we have any alternative in RHEL for password management like cwallet or any suggestions what to should be the best way to achieve this?
Please note that I will invoke this class using shell script.
Thanks
This is tricky, because if someone gets access to your server is already game over. So the solution is not just to encrypt the data, as it won't do much, but you need security in depth.
To put this in context, you can have the password encrypted, salted whatever... When an attacker gets access to the server, he won't be able to read any of those files (even with the encrypted password) unless he is able to become the user running the app. If he manages to do that, he only needs to do a memory dump and then fish for passwords (which is not hard).
So a real world solution is:
Only allow a restricted number of people to log on the server.
Only allow an even smaller number to become the user which runs the application server.
This group of people are the ones who can read/update the properties file
Disable any kind of backups on the files that contain secrets.
Again, encrypting passwords on the files might give you a sense of security, but again, if you follow the steps above, anyone who can read the file, will also be able to read the memory contents of the app. And even if someone does things right and stores that password in an bit of offheap memory, some linux tools can read the whole memory map of a process, so again, game over.
Using encryption in this case just adds obscurity and no real protection.
I have a flat java file that's querying two databases and currently has the credentials hardcoded. The plan is to convert this to spring batch but in the mean time I would like to encrypt them within a config/properties file externally and call them. I'm looking for any specific examples, best practice / solution. I appreciate any time and effort. Thank you!
If you decide to encrypt the credentials, then you have the problem of secure storing the encryption key. The best you can do it to not store it at all and require it to be given manually whenever your application starts up. Your application should use the key to decrypt credentials, connect to any services. Finally it must throw away the key and credentials after use, in order to prevent getting them from memory.
If manual intervention during application startup is unacceptable, then a typical solution is storing the key in a file with appropriately restrictive permissions on an encrypted partition, but if the system gets compromised, e.g. an attacker somehow gets root privileges or privileges of your application, he will be able to recover the database credentials.
I am writing an application, in Java, which needs to log in to a remote SOAP service (JIRA) prior to calling methods on that service.
I have looked at examples of how to do this, for example http://www.j-tricks.com/1/post/2010/8/jira-soap-client.html, however I am concerned that I need to put the password in memory at some point.
I've read that I should store the password as a char[] but still, I'm concerned about storing the password in the clear at all.
How should I store the password used by my client to log into the SOAP service? And how should I read it and pass it to JIRA?
EDIT
This application will be using Spring so it's likely the password would be stored in the bean configuration file rather than in the code.
The SOAP login method returns a string token you can use for the session, so there's no need to store the password in memory after using it. But I think you're talking about longer term usage. Applications will usually have a configuration page to allow a more permanent authentication to be set up, and then require a password to be entered each time that connection is reconfigured.
Here's what I decided on eventually.
First, some clarifications.
The password is encrypted and stored in a database.
The password is statically populated (by the DBA).
This is an exercise in encryption and decryption, therefore hashing algorithms, such as MD5 are not applicable.
I looked into ways of encrypting in SQL and decrypting in Java, but none were particularly good. Therefore I decided upon the following approach.
When the DBA populates the password, they run the DBMS-specific encryption method (e.g. MySQL's encrypt) when entering the password (e.g. insert into creds(user,password) values ('bob',encrypt('password'));
The SQL to retreive the password, passed to the spring application as a property, includes the decryption (e.g. select user,decrypt(password) from creds).
Other than that, this is an exercise in user management and locking down the database. E.g. only certain people (DBAs) get full access and the application uses a read-only user.
Hope this helps someone else in the future.
I am making app, which would send value to php script. Then php script would conncect to Mysql database and return JSON array. And then the app would read it. How to ensure safety? For now I am not using any safety measures.
It depends, this is such a huge topic that a true answer would take a books worth of material.
What 'safety measures' are you asking about?
If you're talking about involving a web server, then you first need to secure your web server and build an API that is smart enough to protect against most common methods of attack. You need to make sure that other people - just by entering something in URL - cannot do the same thing your intended user can do. This means that you need to validate the user before giving them access to API.
Most common method of doing this is sharing a 'secret key' that only the server and client knows. So your user, with a phone, has a specific key and server has a key. Now user sends data to the server and also sends a validation hash (like sha1(KEY+DATA)). Server then receives data and makes sure that the hash is the same. Never send the key itself together with the request.
Another thing you need to test for are replay attacks. If someone listens in on the communication, then you have to limit the damage. This is usually done by you also sending a timestamp with the request and the server checking if the timestamp is within accepted range, so if someone sends that same request again later, it would fail due to timestamp being different. Server checks for this since timestamp is also taken into account for input data validation.
Then you have to make sure that the data returned from server is correct. So server will ALSO build a validation hash that your phone will check, making sure that someone didn't change the data while it was sent back to your phone.
As an added layer, you can also encrypt data that is sent (and received from API) with a heavy cryptography algorithm like AES/Rijndael 256bit encryption. This will encrypt data with a key that is required to open the data. If phone and server know the key and no one else does, then data can be sent securely.
Then the connection should be HTTPS/SSL, which helps protect communication from being listened in. But this does not help if someone already has access to your phone, so it is recommended to use the other mentioned methods as well.
As for your phone, it is pretty secure by itself as long as you don't have apps installed on it that might compromise that security. Also, if you think you can secure your web server less, thinking that since only phones communicate with it that it is safe, then a hacker can easily listen in on communication on their own phone and figure out the basics of your web service API and then open all the doors. So make sure your security layers go from biggest to smallest: web server is by far the biggest entity in your system.
As you can see, this is a MASSIVE topic that can take a long time to learn. But without knowing what exactly you were asking about, I cannot really help you any further.
I'm writing on a Java EE project which will have everything from 3-6 different clients. The project is open source, and I wonder what security mechanisms one could/should use. The problem is: Because it is open source, I would believe that it is possible for anyone with a user to write their own client (maybe not realistic, but truly possible) and make contact with the server/database. I've tried to go through all the scenarios of reading/writing different data to the database as different roles, and I conclude with that I have to have some security mechanism on a higher level than that (it is not enough to check if that account type is allowed to persist that entity with that ID and so on...). In some way I have to know that the client making contact is the correct client I wrote. Could signing the Jar files solve this entire problem, or is there other ways to do it?
-Yngve
I really think that if restricting the available activities on the server side (based on role) is not sufficient, than you've got a bigger problem. Even if a user doesn't write their own client, whatever mechanism you are using for your remote calls is likely to be vulnerable to being intercepted and manipulated. The bottom line is that you should limit the possible calls that can be made against the server, and should treat each call to the server as potentially malicious.
Can you think of an example scenario in which there's a server action that a particular authenticated user would be allowed to take that would be fine if they're using your client but dangerous if they're not using your client? If so I'd argue that you're relying too strongly on your client.
However, rather than just criticize I'd like to try to also offer some actual answers to your question as well. I don't think signing your jar file will be sufficient if you're imagining a malicious user; in general, public-key cryptography may not help you much since the hypothetical malicious user who is reverse-engineering your source will have access to your public key and so can spoof whatever authentication you build in.
Ultimately there has to be someone in the system you trust, and so you have to figure out who that is and base your security around them. For example, let's imagine that there may be many users at a particular company who you don't necessarily trust, and one admin who oversees them, who you do trust. In that scenario you could set up your client so that the admin has to enter a special code at startup, and have that code be kept in memory and passed along with any request. This way, even if the user reverse-engineers your code they won't have the admin code. Of course, the calls from your client to your server will still be vulnerable to being intercepted and manipulated (not to mention that this requirement would be a royal pain in the neck to your users).
Bottom line: if your user's machine is calling your server, than your user is calling your server. Don't trust your user. Limit what they can do, no matter what client they're using.
Well the source may be available for anyone, but the configuration of the deployment and the database certainly isn't. When you deploy the application you can add users with roles. The easiest thing to do is to persist them in a database. Of course the contents of the table will only be accessible to the database administrator. The database administrator will configure the application so that it can access the required tables. When a user tries to log in, he/she must supply a username and password. The application will read the table to authenticate/authorize the user.
This type of security is the most common one. To be really secure you must pass the credentials over a secure path (HTTPS). For a greater degree of security you can use HTTPS client authentication. You do this by generating a public key for every client and signing this with the private key of the server. Then the client needs to send this signed key with every request.
EDIT: A user being able to write his/her own client doesn't make the application less secure. He/she will still not be able to access the application, if it is required to log in first. If the log in is successful, then a session (cookie) will be created and it would be passed with every request. Have a look at Spring security. It does have a rather steep learning curve, but if you do it once, then you can add security in any application at a number of minutes.