I have implemented a routine where when a user submits a form an email is sent to the administrator. For this I have used Java Mail API. And I setup a dummy account on Microsoft Outlook for sending out the emails. In the code I have hard-coded the password. I am concerned this will be a security issue when I host the webpage.
Here is my code.
I have written a private function:
private void getSession(){
this.session = Session.getDefaultInstance(properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication
getPasswordAuthentication() {
return new PasswordAuthentication("xxxxxxxxx@outlook.com", "xxxxx_password_xxx");
}
});
}
In my public execute()
method I call the getSession()
method and generate the message.
public String execute() throws Exception {
getSession();
Message message = new MimeMessage(this.session);
message.setFrom(new InternetAddress("xxxxxxxxxxxxx@outlook.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("admins.email@xxxxx.com"));
message.setSubject("Form submit notification");
//...
}
Is it secure to hard code the password in the session method when I host the web page?
And if not, then some pointers to implement the alternatives.
Thanks!
In this case he can't hash the password. A password can be hashed only when it needs to be CHECKED and not USED. Using the password (i.e. the back end needs to login to an SMTP server to send an email, or to another database to extract data) implies the need to know it.
There are 3+1 levels of alternatives in this case, basically shifting the insecurity from the code to somewhere else. But the attacker will always be able to recover the password given the same pre-conditions of the program. The likelihood of getting to them measures the level of security of that password.
- in clear-text, in a configuration file - the password can be stored in a
configuration file somewhere in the filesystem; clearly if it is a
webapp, it must not be the webroot, but somewhere else well protected
- encrypted in a configuration file; the key for encryption/decryption must be stored in a
different file, and not in the code. This method best applies when
the two files are stored in different filesystems
- encrypted in a configuration file; the key for encryption/decryption is not stored
on any filesystem. It is asked at boot to the operator that is
starting the application; a check is made whether this key is the
right one (otherwise, the application can't start) and if it is, it
is stored in memory.
- [not a real alternative for common people] HSM Hardware Security Module: this type of device stores key and values in a "secure" way. This usually means the server (your
application) has a PCI/hardware module that physically grants the
connection and the retrieval of some keys stored in the HSM. The key
for decryption of the config file is stored in the HSM and due to
the fact the server connecting has the PCI hardware, it can
retrieves that key and decrypt the config file.
A raking of the risk of these solutions
0-- Password hardcoded in srcs --> The risk is connected to the ease of retrieval of the code; decompilation to extract harcoded strings is not difficult even in C/C++, in Java and .NET is trivial and instant
- Password in a config file, cleartext --> The risk is connected to the ease of retrieval of a specific file in the filesystem; usually this is harder as the code is shared in repositories, shared among different people, while the filesystem hosting the app is accessed by less people
- Password in a config file, encrypted --> The risk is the same above! I know it sounds strange, but trust me: having a password encrypted with a key "close" to it, or having it in cleartext is the same!
- Password in a config file, encrypted, no key stored --> The risk is connected to the ease of reading the memory in the server running the password. In C/C++ you need to be root AFAIK. In Java you can do it being the same user who launched the process. In both cases it needs complete access to the system
- Password in a config file, encrypted, key in the HSM --> You have to get the full control of the server, usually being root, and then understand which API the HSM has to retrieve the key. It is connected to the likelihood of having complete access to the server.
Of course, from 1 to 3, the implementation gets much harder. 4 is a matter of the HSM's api.
It is not a good software practice and can lead to security problems.
It could also cause problems down the road when the password changes. You will have to re-compile the code in order for the application to be updated.
Here is one suggested way of not having to hard code your password and therefore allowing for your software to be more flexible and secure.
CWE-259: Use of Hard-coded Password
As suggested in the above link:
Apply strong one-way hashes to your passwords and store those hashes in a configuration file or database with appropriate access control. That way, theft of the file/database still requires the attacker to try to crack the password. When receiving an incoming password during authentication, take the hash of the password and compare it to the hash that you have saved.
Use randomly assigned salts for each separate hash that you generate. This increases the amount of computation that an attacker needs to conduct a brute-force attack, possibly limiting the effectiveness of the rainbow table method.