How to protect sensitive information inside context.xml? - java

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.

Related

Encrypting application properties in Spring Boot

So I've done some Googling and read some of the documentation on Spring Cloud, but in an effort to truly punish myself, I'm seeking to understand just exactly how encrypting sensitive application properties with a "{cipher}" really works.
For example in an application.yml...
Spring.datasource.password: '{cipher} abdjdbdjfb15168gddbdk3900289'
My understanding is that it is safe to commit this to a repo and that spring boot uses an encrypt.key in bootstrap.yml in order to decrypt it when needed.
What I don't understand is why is it safe to commit the encrypt.key to the repo? And if you don't, then how am I supposed to utilize this?
I also found a link on the heroku documentation that you maybe set this as a configuration variable in the server?
Bottom line, I have a lot of questions and, most importantly, I am not even sure what questions I need to be asking. So I'm hoping someone out there that knows what they're doing can point me in a few right directions of some links to read etc to get me going please?
Thanks in advance!
First of all, checkout the reference documentation about encryption in Spring Cloud Config which explains possibilities of configuration support.
You should never commit sensitive data such as keys to a source code repository if you can't control access to that repository. Not only regular access but also physical access, backups, ….
The preferred approach how to handle keys is storing the key in as few places as possible, ideally only on the server side where decryption happens. There you have the option to either use a bootstrap config, system properties or environment variables as a mechanism to pass the key to your runtime.
You might want to peek into HashiCorp Vault support as Vault solves the chicken-egg problem of key management. Instead, you can obtain a Vault token (from inside your client application, or configure a token on the server) and Vault will handle encryption/decryption for you.

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.

How to set-up Persistent Storage for eclipse-tomcat for backup and streaming (not using database)?

I am working on a Java Web-Application project using servlets, eclipse, and tomcat.
I would like to be able to dynamically store/create persistent files from servlets and allow the user to access the files using a link, without storing the files in the database.
I have read that getServletContext().getRealPath("/") is volatile and gets reset every time the server is restarted.
I have also read that creating a directory like "$HOME/.ourapp" would solve this. Although, I cannot seem to find how to set-up tomcat to allow the user to access the files using a link, using the eclipse-tomcat.
Question : How to set-up eclipse-tomcat so that the link to the website "http://localhost/" and the file "http://localhost/temp-xx.txt" is the same, while also allowing to dynamically create persistent data "temp-xx.txt" is generated by a servlet and allow the user to access it and does not get deleted when the server is restarted.
This gets complicated, because Tomcat can server files using DefaultServlet (it just sends files back to the client, exactly as you'd expect from a web server), but it caches files internally, so modifying the file system underneath it can have some surprising behavior.
You can disable caching for the DefaultServlet but I've seen reports that it still behaves in surprising ways. The only fool-proof solution I've seen is to write your own servlet that streams the files from wherever they are stored.
But writing your own streaming servlet isn't as simple as you might think. If you want it to be high-performance, you'll want to enable all the nice HTTP features like range-requests, eTags, If-Modified-Since and all that stuff that the DefaultServlet already provides. Perhaps you should start with using the DefaultServlet and see how far it will get you.
The configuration is actually really easy: just add a <Resources> element to your META-INF/context.xml file and use a postResources attribute. You can find the documentation in the Tomcat users' guide for resources.

Is using a property files a safe option?

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.

Categories