Is using a property files a safe option? - java

I have a requirement to use property files to have some important information which should not be revealed to anyone.
My question is : regarding security concern, is using a property file a safe option or not ?

This depends on a larger context (security policy of the whole solution) and the nature of data you want to keep secure.
In most environments, a secure network is constructed by using firewalls etc., and inside, even sensitive information (like API keys) are stored in property files etc. as plain text. There are more sophisticated solutions that can keep these information encrypted, but it requires considerable setup.
Some people suggest embedding a encryption key in the source to encrypt the property files and then obfuscating the source to hide the encryption key, but this is security through obscurity and should be avoided.
If you are storing password information to authenticate users etc., then you should store salted hash of passwords.
EDIT:
Probably one of the best way would be to encrypt the property file and let operators type the encryption keys every time the app. starts (to avoid storing the encryption key in a persistent store). Note however, an attacker could still read the process memory to get the decrypted value.
This is why most solutions focus on securing the network, rather than protecting against an attacker who already has access to the servers.

You have at least two choices:
read properties value from system properties configured only in the operating system of the deployment server
read properties value by lookin up JNDI name, so your properties value are configured in the application server
With each of the above approaches security concerns can be addressed focusing on the deployment environment and not focusing on the application sources or binary.

Ask back. There are two options: a configuration inside the application, and outside the application, in the Java EE server. I think they meant to have the properties file outside the application. You should ask that.
Having it outside the application also allows deploying the app in different environments. And is more secure as even the developer does not need to store somewhere the production password.
How to access the file depends a bit on the server.

Related

Spring Data read MongoDB password from a vault or other protected source

Currently, my spring-boot application connects to a local MongoDB without credentials. To be able to install it at a customer I need to provide the capability to use username and password for the DB connection. I am using the application.properties file, which currently contains only these 3 lines related to the database:
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=myApp
There would be these two additional ones:
spring.data.mongodb.username
spring.data.mongodb.password
But of course, I don't want to have the password in plain text within this file, or even worse in our git. One option would be to provide them as a parameter with a start script but then again it would be readable as plain text in the process details.
I've seen some encryption in the properties file using Jasypt, but I don't understand how this approach would work in my case. I never explicitly use these properties as they are automatically taken by spring to do the connection.
What would be the safest approach?
TL; DR
It depends on your security/risk profile, which method is acceptable.
The longer read
Your question is: What would be the safest approach?
A simple answer to this question is not storing the password anywhere but letting an operator type it in. Obviously, that's not the answer you're looking for as with servers in data centers or even VM's in the cloud this approach isn't feasible.
To understand what method is safe enough and which one is acceptable, it's important to understand your organizational context, its willingness to accept risk and the resulting consequence which is the requirement for handling secrets. This evaluation can result that for one organization it may be fine storing credentials in plain text (because the environment is secured or there's a low threat associated on exposed secrets), others require encryption with proper key management and auditing.
You're already describing that storing credentials in Git isn't a proper option. So I assume that you're looking towards a method that protects the actual secret in some way. Protection can happen on different levels:
Storing secrets in a protected place with access control applied
An environment variable on a host that is access protected
An access-controlled file with protected by permissions
Storing secrets in the encrypted form
Encrypting the value and storing it in a file. Here you need to consider who has access to this file and what about key management. Introduces sort of chicken and egg problem
Encrypting the value and storing it in memory. Still, you need to solve the key management issue.
Retrieving the secret from a trusted source
Credentials are typed in by an ops person (Not really feasible)
Asking a service to provide you with the credential. The remote service protects the secret and allows you/your application to ask for the secret.
There are potentially more possibilities but let's stick with these for now. One aspect that is associated with the above-mentioned possibilities is the transport of the credential from the source to the target destination. Transport typically spans over one to many parties and each of these parties need to be trusted in some way (i.e. you must make sure a certain party does not divulge your credentials). This pattern is also known as chain of trust. If every hop in the chain of trust is known, to not expose your credentials, then you can react with a particular protection pattern to this context. If you find a weak link that elevates the risk of exposure (e.g. a public folder, Lookup by an operator), then you again need to increase the level of protection according to your needs.
Having all that said, let's take a look which possibilities you have with Spring Boot to apply protection of secrets:
Environment variables
You can store configuration using environment variables or system properties. The aspect of volatility distinguishes from a persistent (e.g., file-based) storage. Variables can be set before/upon application startup.
Example for environment variables:
export SPRING_DATA_MONGODB_USERNAME=…
export SPRING_DATA_MONGODB_PASSWORD=…
java -jar my-app.jar
Examples for system properties:
java -jar my-app.jar -Dspring.data.mongodb.username=… -Dspring.data.mongodb.password=…
java -jar my-app.jar --spring.data.mongodb.username=… --spring.data.mongodb.password=…
Please note that environment variables/command lines can be introspected by the /proc file system and tools like ps
See the reference documentation on Externalized Configuration for further details.
Encrypted Configuration Properties
Spring Cloud comes with crypto support for individual properties. You can encrypt selected properties with different keys and key types (symmetric, asymmetric). This approach allows you to select properties that should be encrypted without the need to encrypt the whole file.
Example for environment variables:
application.properties
spring.data.mongodb.password={cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
Please note this approach introduces the requirement of property key management.
See the reference documentation on Spring Cloud Config Encryption and Decryption for further details.
Application-controlled secrets
Configuration Properties in Spring Boot are obtained from the Environment and provided by PropertySources. You can contribute either properties or an entire PropertySource before spinning up Spring Boot.
Example of adding a PropertySource:
SpringApplication app = new SpringApplication(DemoApplication.class);
app.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.getEnvironment().getPropertySources().addFirst(…);
}
});
app.run(args);
Example of adding a property:
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setDefaultProperties(Collections.singletonMap("spring.data.mongodb.password", "…"));
app.run(args);
Remote Configuration Properties
Spring Cloud Config allows you to centralize configuration that is served by Spring Cloud Config Server. Properties are no longer stored locally, but served from a config service that can be secured differently than your application protection level. To setup Spring Cloud Config Server, you need an additional service and integrate the client dependency in your application.
Please note that this approach does not solve the overall problem, but just moves it into someone else's responsibility.
See the reference documentation on Spring Cloud Config Server for further details.
Using Secrets Management
If you can afford a Secrets Management, such as HashiCorp Vault, CredHub, Azure KeyVault, Kubernetes Secrets, then you can leverage the features of your platform/Secrets Management system to apply protection to your credentials.
Secret Management systems typically handle encryption, auditing, and access control for you. These systems keep an encrypted copy of the credential. Once you request the credential (typically over TLS secured connections), the system checks whether you/your application is allowed to access that secret or not.
Some of these systems also provide dynamic secrets. Dynamic secrets are generated for a particular application instance upon demand. If your application wants to connect to MongoDB, the secrets management system is going to create a credentials pair and server these to your application. When your application stops, then the secrets management system is going to revoke the credentials.
See the reference documentation on Spring Cloud Vault for further details.
One addendum to the answer from #mp911de:
There is a second file option in Spring Boot: You are able to provide an additional file to overwrite the standard config, by providing either a ENV variable SPRING_CONFIG_ADDITIONAL_LOCATION to a file or adding it as a command property like spring.config.additional-location, see Application Property Files.
This could give you the opportunity to add the credentials via some file base secret deployment (eg. Kubernetes secrets used as a volumeMounts, Puppet/Chef/Ansible based secret deployment etc.).

Proper way of hiding very sensitive credentials in a web application

I am currently developing a spring boot web application. It is a REST api proxy that connects to another api using some very sensitive credentials. The credentials are hard-coded at the moment, but obviously they should not be. What is the proper way of hiding them?
I have considered using some library, like jasypt to encode them and put the encoded values in a properties file, with the key hidden somewhere, perhaps in system variable, (but it is just another layer of obfuscation, isn't it?)
How can I properly hide these sensitive credentials?
You can use your server environment to hide your properties. Just store on your production server application.properties with real credentials and protect access, so only your application will have access to the property file.
The fundamental problem is that if you ever need to hold security credentials in the clear in the memory of a computer program, AND there are people who have the equivalent of "root" access to the machine, then it is possible for one of those people to gain access to the credentials.
So you need to design your security so that that the credentials never need to be held in the server's memory.
If you are really serious about solving this, you need to investigate Hardware Security Modules. However, the HSM approach is going to be complicated and expensive, and may require you to rework your authentication protocols.

How do you securely provide a sensitive info (e.g. password) to a background application to be started?

I am working on a Java application that should be run in the background and was thinking of externalizing some sensitive info (DB credentials among others) in case it should change. These info is required in order for the application to start. However, I was wondering what is the proper way of doing this?
I was thinking of the following but needs advice from a security standpoint.
Encrypted passwords will be passed as Main arguments when starting the application. However, I noticed that any user can see the arguments when the list of processes in the OS will be viewed.
Generate an external file, i.e. java properties file (with encrypted credentials) with view restrictions, and pass the file path to the application
Put the encrypted credentials in the user's environment variables for the application to access it
Note: We already have an encryption tool that we use
Personally, I was leaning to the 2nd option but I would like to know suggestions, comments, or best practices for cases like this.
Thanks!
2 is the most sensible option. Problem with 1 and 3 is, once they have access to the "encrypted" string, all they have to figure out how are you decrypting it (You anyway have to do it, to make use of it).
Have you looked at Spring Cloud Config, I don't know whether this is an option for your or not.
Option 2 is most common.
Personally, I do not recommend Option 1 and 3.
There could be other options too.
As example you can look at PicketBox Vault.
It allows to make custom implementation more secured than default.
In fact it is extended option 2 - there is a Vault file protected by key stored in Keystore.
Still password to that Keystore(alias) must be secured, but only one(two). It is useful, when there are many properties need to be secured. It is also more manageable, since all properties secured same way and in one place.

What is the best practices in Java for secure storage of data?

I have java application and I need save passwords into encrypted file. I got advice to use Windows API. I found JDPAPI what is JNI wrapper around the MS DPAPI. It seems good. But I want to know does another libraries or methods exist to use Windows API for secure storage of data into file? Or does some methods exist for secure storage in Java without using Windows API? I never use secure storage. Can you talk me about the best practices in Java for secure storage of data with and without Windows API?
First: Using Windows API is kind of senseless. Even when you can't imagine that, it might be possible that you have to migrate.
Second: Storing a password encrypted only makes sense when you enter the encryption key during the applications runtime. If you store it in a configuration file, it does not make any sense.
The encryption key could be stored as a thread local variable after it was entered.
I would suggest using property files and encrypt and decrypt the values in a service layer using bouncy castle. This way you can mix encrypted and unencrypted values in the same file.
You could of course use Spring and do the necessary stuff quite easily using Spring security crypto.
In case we are talking of a web app using hibernate, I'd suggest using properties stored in a database and use jasypt for transparent encryption.

How to protect sensitive information inside context.xml?

I just started storing all of my DB credentials in my WAR's context.xml file, and loading them through JNDI. This way, my app can reuse the same credentials in multiple areas, and I can use JNDI to retrieve them (instead of sprinkling the credentials all over my codebase).
But now I'm thinking: what if an attacker gets onto the machine wehere my Tomcat server is installed? They could go straight to my webapps/MyApp exploded directory, find & open up the context.xml directory, and voila - they can now access my database!
So what is the next step for introducing security here? Is there a way to keep all of my credentials in some keystore, and reference their labels from inside context.xml? I still would like to use context.xml so that my JDBC code can access the credentials through JNDI. If so, how does context.xml access them in a secure way? What is the normal way of dealing with security here? Thanks in advance!
I would recommend building an encryption system that encrypts the data before it gets sent to the xml file then instead of searching for the username or whatever you encrypt the name before you search. This way even if a person managed to get into the file the wont be able to read it without having the algorithm used for encrytion and knowing exactly what they wanted to find. Well theoretically they could brute force it, but they still need to know the algorithm to do that. An easy way to handle encrytion would be to learn how to use the bouncy castle libs at http://www.bouncycastle.org/ . They have a very easy to use/learn system.

Categories