How to avoid storing passwords in the clear for tomcat's server.xml Resource definition of a DataSource?

configuration, jdbc, tomcat

Solution

As said before encrypting passwords is just moving the problem somewhere else.

Anyway, it's quite simple. Just write a class with static fields for your secret key and so on, and static methods to encrypt, decrypt your passwords. Encrypt your password in Tomcat's configuration file (`server.xml` or `yourapp.xml`...) using this class.

And to decrypt the password "on the fly" in Tomcat, extend the DBCP's `BasicDataSourceFactory` and use this factory in your resource.

It will look like:

    <Resource
        name="jdbc/myDataSource"
        auth="Container"
        type="javax.sql.DataSource"
        username="user"
        password="encryptedpassword"
        driverClassName="driverClass"
        factory="mypackage.MyCustomBasicDataSourceFactory"
        url="jdbc:blabla://..."/>

And for the custom factory:

package mypackage;

....

public class MyCustomBasicDataSourceFactory extends org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory {

@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
    Object o = super.getObjectInstance(obj, name, nameCtx, environment);
    if (o != null) {
        BasicDataSource ds = (BasicDataSource) o;
        if (ds.getPassword() != null && ds.getPassword().length() > 0) {
            String pwd = MyPasswordUtilClass.unscramblePassword(ds.getPassword());
            ds.setPassword(pwd);
        }
        return ds;
    } else {
        return null;
    }
}

Hope this helps.

Problem

The resource definition in tomcat's `server.xml` looks something like this... ``` <Resource name="jdbc/tox" scope="Shareable" type="javax.sql.DataSource" url="jdbc:oracle:thin:@yourDBserver.yourCompany.com:1521:yourDBsid" driverClassName="oracle.jdbc.pool.OracleDataSource" username="tox" password="toxbaby" maxIdle="3" maxActive="10" removeAbandoned="true" removeAbandonedTimeout="60" testOnBorrow="true" validationQuery="select * from dual" logAbandoned="true" debug="99"/> ``` The password is in the clear. How to avoid this?

Original source