1

I am maintaining an existing Java product (which has a HUGE code-base). I discovered that it is setting (and getting) two of its internal passwords as Java system properties, at no less than 4-5 different places (methods). Now, the problem is, the passwords are being stored as plain text in the Java system properties, and so, the same is visible to external entities, as the application is not using any Java Security Manager. For example, if the application (process) is running on port number 1234, we can run the Java command:

jinfo -sysprops 1234

to view both the passwords as values of the corresponding Java system properties. I wish to ask if there is any remedy to this without changing the existing code-base too much? The desired effect would be to "hide" the two Java system properties (denoting the two passwords) from all external entities.

It may be noted that introducing a Java Security Manager into the application may not be a solution, as if we revoke read permissions from the said two Java system properties using the Java Security Manager, the application codes which read those properties would crash. Same is applicable for storing the passwords in encrypted form, as that would crash all codes within the application which are expecting to read the passwords in clear text form.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

1 Answers1

1

Since you said:

...at no less than 4-5 different places...

and you really don't want to do major code changes, I would:

  1. Supply the password in an encrypted form.
  2. Go through those 4-5 places (it's not so much!), and call a wrapper method that you have to write separately: MyPassUtil.getXYZPassword() which internally calls the System.getProperty() to get the encrypted password, decrypt it, and return the plain text version to whoever is calling it.

Keep in mind though, that this way, the decryption key and algorithm is stored within the application, and a good Java decompiler (JD-GUI or CFR) will still return this information. In other words, anyone with the access to the JAR file, can still get the information with some minor effort, something which I presume, since one can call jinfo, they can also get the JAR file.

The best is to use some form of keystore, which again, you can easily implement once you do the wrapper method mentioned in step 2, without affecting whoever is using it.

Also, some security tips:

If it's an SSH / SFTP connection, set up SSH keys between the two machines, and eliminate use of passwords.

If it's a database connection, at least configure the DBMS to allow connections only from this particular machine's IP address. If the connection is over the internet and you are behind an NAT, set-up a VPN first, and channel the traffic between the hosts through it.

For other setups, try and see whether there are some other tips you can do similar to these two points, to improve the security around these passwords.

Franco
  • 53
  • 5
  • Thanks for the quick reply! To give you a bit more context, the said two passwords we are storing as Java system properties are actually passwords to access two key-stores, and Tomcat requires that we store the said two passwords in plain-text format. Given this, can you suggest any other workarounds, such that only Tomcat will be able to see the two passwords as-is, while they will be invisible to all other external entities? – Subhayan Mukherjee Oct 21 '14 at 06:55
  • I understand. At the end of the day, a decryption key must be put somewhere. If I understand your scenario correctly, you are using the Tomcat configuration to add the passwords into the System properties of the application, after which the Java application gets these passwords and unlocks the key store. I can only see two options: 1. Encrypt the passwords and decrypt them in the java application as explained in the previous comment. 2. During startup (of the app), ask for the password to be inputted interactively (manually typed). This way, the password is only stored in RAM during runtime – Franco Oct 21 '14 at 18:53