What is the standard for PROD database password in the Springboot fat jar application connecting a database - spring-boot

I have a springboot application which connects to database, currently the database password is in plain text inside the application properties.
What is the standard for securely protecting password in PROD environment?
How to change the database password if the application password is inside the application properties which is built in as part of the JAR and especially when the application is live?

You could use jasypt to handle the encryption and then use Jasypt's Spring integration or this Jasypt Spring Boot Starter to wire it into Spring.
This will allow you to define an encrypted database password property, for example in application.properties e.g.
db.password=ENC(.....)
The other part of your question is:
How to change the database password if the application password is inside the application properties
You can do this by overring properties defined in your properties file with system properties. For example: -Ddb.password='....'. You could also define an additional properties source which is external to your JAR and can be edited at runtime. For example:
#PropertySources({
#PropertySource(value = "classpath:/**.properties"),
#PropertySource(value = "file:/some/external/directory/override.properties", ignoreResourceNotFound = true)
})
public class Application {
// ...
}
Creating the file /some/external/directory/override.properties and populating it with db.password=... would cause your application - on next restart - to use that property value.

Related

Springboot: Spring JPA - How to get datasource properties from server container

I use WAS Liberty Server container which provides server.xml and server.env file for configuring many things in addition to configuring DataSource properties such as url, username, password etc.
For security reasons, these properties are not known to developers for production Liberty servers. However, developers use same server.xml/server.evn files but with different DataSource properties so they can do their work.
So, I might have two server.env files like:
PRODUCTION server.env: dataSourceUrl="server-A-URL" (this URL is not known to developers)
DEVELOPMENT server.env: dataSourceUrl="server-B-URL" (this URL is known to developers)
, then the dataSourceUrl is used in server.xml files in production and development to set the url accordingly.
So, the structure of server.xml/server.env file is same for developers and production, only the DataSource url, username, password are different. This way developers can work using their own DataSource properties and once ready to deploy they app, it is handed to other team which then just changes the DataSource properties to the production values and deploys the application to production server.
With Springboot JPA, I know we can use application.properties file to set these DataSource values. But, we would like to be able to set these to the values located in server.env file. Basically to have something like this in application.properties file:
spring.datasource.url=dataSourceUrl //dataSourceUrl is set in server.env
, then be able to use this value in Java code using #Value injection like:
public class MyClass {
#Value("${spring.datasource.url}")
String dsUrl;
...
}
I have been reading about externalizing properties but I am not able to figure out how to do this
You can use Liberty's jndiEntry elements to make configured values available in JNDI. You will need the jndi-1.0 feature, after which you can configure,
<jndiEntry jndiName="spring/datasource/url" value="${dataSourceUrl}"/>
and access it in your application as:
String dsUrl = InitialContext.doLookup("spring/datasource/url");
Or, from a web or ejb component as:
#Resource(lookup = "spring/datasource/url")
String dsUrl;

Session cookie custom path

I have an spring boot application and want to deploy it to wildfly12. What I'm trying to achieve is that to set a custom path for JSESSIONID cookie. But after all, my efforts haven't had any results.
I have tried to use this property in my application.properties file:
server.servlet.session.cookie.path=/
When I run the application with the embedded tomcat, everything works fine; But when I deploy my app to wildfly, regardless of the value of that property, it always sets the cookie path to the "context-path" of the application.
I have also tried to use this property also:
server.servlet.context-path=/
but no success so far!
There is also this tag inside the standalone.xml file:
<session-cookie http-only="true" secure="true"/>
but it seems that it has nothing to do with the cookie path, as it doesn't have any property regarding that.
The configuration you are doing is for the embedded server of spring boot application.
Embedded server settings present in application properties (can be check here the section # EMBEDDED SERVER CONFIGURATION and the namespace server.servlet.session.cookie.*).
To modify cookie related configuration on external servers, you have to create CookieSerializer bean which can be used to customize cookie configuration. e.g.
#Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
You can refer spring guide for more information.

Spring boot application properties load process change programatically to improve security

I have spring boot micro-service with database credentials define in the application properties.
spring.datasource.url=<<url>>
spring.datasource.username=<<username>>
spring.datasource.password=<<password>>
We do not use spring data source to create the connection manually. Only Spring create the database connection with JPA.(org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration)
We only provide the application properties, but spring create the connections automatically to use with the database connection pool.
Our requirement to enhance the security without using db properties in clear text. Two possible methods.
Encrypt the database credentials
Use the AWS secret manager. (then get the credential with the application load)
For the option1, jasypt can be used, since we are just providing the properties only and do not want to create the data source manually, how to do to understand by the spring framework is the problem. If better I can get some working sample or methods.
Regarding the option-2,
first we need to define secretName.
use the secertName and get the database credentials from AWS secret manager.
update the application.properties programatically to understand by spring framework. (I need to know this step)
I need to use either option1 and option2. Mentioned the issues with each option.
What you could do is use environment variables for your properties. You can use them like this:
spring.datasource.url=${SECRET_URL}
You could then retrieve these and start your Spring process using a ProcessBuilder. (Or set the variables any other way)
I have found the solution for my problem.
We need to define org.springframework.context.ApplicationListenerin spring.factories file. It should define the required application context listener like below.
org.springframework.context.ApplicationListener=com.sample.PropsLoader
PropsLoader class is like this.
public class PropsLoader implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
String appEnv = environment.getProperty("application.env");
//set new properties based on the application environment.
// calling other methods and depends on the enviornment and get the required value set
Properties props = new Properties();
props.put("new_property", "value");
environment.getPropertySources().addFirst(new PropertiesPropertySource("props", props));
}
}
spring.factories file should define under the resources package and META-INF
folder.
This will set the application context with new properties before loading any other beans.

Hide passwords in application properties of Spring boot application

Whenever the question of hiding the fields like passwords in application properties file arises,the straight-forward answer is encrypt those details using jasypt or other encryption.
If you keep encrypted passwords and jasypt details in same file, how does that make sense? or may be keep them in different file..
Any other smarter way for this?
You're not supposed to save the encryption key in application.properties, after all you don't want it going to your repository. You have to provide the key to your application when you run it, either by typing it or by storing it somewhere on your server. Check this thread for examples.
Let's assume that you have gotten your passwords in a typical application.properties file. Using Jaspyt, you may encrypt as follows:
Maven setup.... Grab the latest spring boot starter Jasypt POM, use
com.github.ulisesbocchio as the group ID.
Create a tiny utility class (preferably outside your spring boot app) to encrypt your passwords; it's easy to use Jasypt's BasicTextEncryptor class ex:
BasicTextEncryptor pwdEncrypt = new BasicTextEncryptor();
pwdEncrypt.setPassword(your_secret_sauce)//whatever you use here will be needed in the properties file (more on that later)
String encoded = pwdEncrypt.encrypt(password_you_want_to_encrpyt);
The String encoded is PBE-encoded by default; grab that
In your properties file, make the following entries:
jasypt.encryptor.password=your_secret_sauce //used in your utility
password_entry_you_want_to_encrypt=ENC(encoded) //encoded grabbed from your utility class
I'll assume that you're annotating your main class with
#SpringBootApplication. Add the following annotations as well:
#EnableEncryptableProperties
#PropertySource(name="EncryptedProperties", value = "classpath:application.properties")
Use jasypt to encrypt properties in application.properties file.
it's usesPBEWithMD5AndDES for the encryption.
See:
https://github.com/ulisesbocchio/jasypt-spring-boot

jasypt encryption not working in spring boot

I want to do encryption for some sensitive data in application.properties file of spring boot application.
for that I have used jasypt-spring-boot-starter plugin .
also used #EnableEncryptableProperties tag on spring application.
I have encrypted access key for my database and written its encrypted value in the property file.
com.test.SharedAccessKey=ENC(vfQQ9veC1G+RV8BC0VA==)
also provided in property file
jasypt.encryptor.password=secretpassword
jasypt.encryptor.algorithm=PBEWithMD5AndDES
I am accessing this property in spring boot application as followes
#Value("${com.test.SharedAccessKey}")
public String shareAcessKey;
But logger.info(shareAcessKey) print as it is ENC(vfQQ9veC1G+RV8BC0VA==)
what I am missing in above , can anyone help.
Issue was resolved . I have done some configuration in my spring Configuration class #Configuration related to property file.
as set property place holder configure to setIgnoreUnresolvablePlaceholders
after removing above code . Jasypt password is got picked up.

Resources