Learning Center
Plans & pricing Sign in
Sign Out

SOAWorl Enterpr OpenSour C Enterpr OpenSour C Enterpr


									                                                                                                                                                             Case Study

                Securing Tomcat Database Passwords                                                                                                              by Michael J. Remijan
                How encrypting the username and password can be implemented

                                        omcat is a great reference implemen-      ObjectFactory. This class is responsible for      and password is even necessary. The general
                                        tation of the Java EE specification and    returning objects of the type defined by the       consensus seemed to be this security is not
                                        is intended for desktop use by devel-     type attribute of the <Resource/> tag. The        necessary for two reasons. One, if an intruder
                                        opers who are starting to learn about     rest of the name/value pairs of <param-           compromises a production server in a way
                                Java EE or those who work on enterprise           eter/> tags are passed to the “factory” in a      that would allow read access to server.xml
                                applications and need an EE server for devel-     javax.naming.Reference object.                    then the clear text username and password
                                opment. However because Tomcat is free it            Finally, the application has to be config-      is the least security concern. Two, Tomcat is a
                                finds its way into production environments.        ured to use this data source. This is done        reference implementation so it shouldn’t be
                                In this environment there are features of         by referencing the data source in /META-          used in a production environment. Although
                                Tomcat that don’t pass security audit reviews.    INF/context.xml of the application’s WAR. A       these are lively debates and can spark great
                                One of these features is the use of clear text    <ResourceLink/> tag is added to context.xml.      topics of conversation they do not address
                                passwords in the server.xml file to create                                                           the issue. What I need is a way to get rid of the
                                data sources. The purpose of this article is to   <ResourceLink                                     clear text username and password.
                                show how encryption of the username and                global=”jdbc/TestDB”                             I will present three possible solutions to
                                password can be implemented thus closing a             name=”jdbc/SpiderMan”                        this issue. The first two are custom solutions
                                potential security vulnerability.                      type=”javax.sql.DataSource”                  involving application updates while the third
                                   Configuring a container managed data            />                                                takes advantage of Tomcat’s built-in extensi-
                                source with Tomcat is easy and well docu-                                                           bility, requires no application updates and so
                                mented under the “JDBC DataSources”                   The type attribute is the fully quali-        is a much more attractive solution.
                                section of Tomcat’s documentation (this           fied name of the class returned when the               The first solution is to bypass Tomcat
                                article uses Tomcat 5.0.28). The data source      resource is looked up using JNDI. The global      altogether and not configure a data source.
                                configuration information is stored in             attribute must match a <Resource/> tag            With no data source there’s no clear text
                                TOMCAT/conf/server.xml. The resource is           in server.xml. The name attribute defines          username and password in server.xml so
                                defined using the <Resource/> tag.                 where the resource is bound in JNDI. From         the problem is solved. However applications
                                                                                  an application’s point of view, the location      still need database connections. With no
                                <Resource                                         specified by the name attribute is relative        container-managed database pool each ap-
                                     name=”jdbc/TestDB”                           to java:comp/env. Each application can            plication will have to do its own pooling. This
                                     auth=”Container”                             have its own conventions for JNDI lookup          brings up all sorts of problems. Applications
                                     type=”javax.sql.DataSource”                  names and the <ResourceLink/> tag is the          will need knowledge of the database and
                                />                                                bridge between how an application does a          how to access it, unnecessary plumbing code
                                                                                  resource lookup and where the resource is         is needed to manage the pool, data access
                                   The name attribute defines where the            actually located. It’s good practice to have      objects will no longer be coded to EE specs
                                resource is bound in JNDI. The auth at-           the application use an atypical lookup            making them less portable, no built-in or
     Michael J. Remijan is      tribute will have either the value Application    name. This makes your application more            plug-in transaction management resulting in
       a Senior Application     or Container. Container means Tomcat will         portable to other EE servers because it’s not     more plumbing code, an ever-growing num-
Developer at Monsanto in        provide the username and password to              accidentally bound to the conventions of          ber of connections as more applications are
St. Louis, MO. He designs       connect to the resource whereas Applica-          one EE server’s resource placement.               developed, performance degradation during
     and develops mission       tion means the application will provide               For development environments or               high-traffic periods as connections become
  critical EE applications.     them. Container is specified because the           personal use this configuration is accept-         scarce, support overhead from managing
        Michael has a BS in     username and password will be entered             able, however, in a production environment        many individual configurations, and the list
 Mathematics/Computer           in server.xml. The type attribute is the fully    the clear text username and password in           goes on. It’s possible each of these problems
 Science from the Univer-       qualified name of the class returned when          <ResourceParams/> is a security vulnerabil-       can be solved but as you solve them your
     sity of Illinois, MBA in   the resource is looked up using JNDI.             ity. If a production server is compromised,       code moves further and further from the EE
 Technology Mangement              Next the resource needs to be configured.       the intruder would have easy access to            specs. Because of all these problems, this is
   from the University of       This is the purpose of the <ResourcePa-           production data. With privacy concerns and        not an attractive solution.
    Phoenix. Sun Certified       rams/> tag. For a JDBC resource, a basic          Sarbanes-Oxley requirements the harder it is          The second solution is to move the re-
  Web Component Devel-          configuration is presented in Listing 1.           for an intruder to gain access to such data the   sponsibility for database authentication from
oper. Pursuant Masters in          The name attribute has the value jdbc/         better.                                           Tomcat to the application. Recall the auth
        Computer Science.       TestDB, which must match a <Resource/>                While Yahooing! I was surprised to dis-       attribute of the <Resource/> tag. If the value
                                tag. The “factory” name/value pair tells          cover I couldn’t find any instructions address-    is Application, the application is responsible           Tomcat the fully qualified name of the             ing this issue. Most search results related to    for providing the username and password.
                                class that implements javax.naming.spi.           debating if securing the clear text username      The Tomcat administrator can delete the

      28       June 2007                                                                                                                                   

     username and password parameters from                  public static DataSource                                <value>postgres_pass</value>
     server.xml and the Developer would code the                 createDataSource(                                 </parameter>
     username and password into the application.            Properties p
     Typically the first time JNDI is used to look up a      )                                                         These strings have corresponding constants
     DataSource is when the username and password                                                                 in the BasicDataSourceFactory class but the con-
     are set. The code in Listing 2 gives an idea of            Tomcat creates an instance of BasicDa-            stants are declared private so can’t be used. The
     what this would look like for Tomcat. Although         taSourceFactory by calling its no-argument            find() method throws an exception if not found
     the example doesn’t use any kind of encryption         constructor. When a DataSource is needed the          because decryption will fail if there’s nothing to
     it’s not difficult to plug in an encryption strategy.   getObjectInstance(…) method is called. The            decrypt. The decrypt() method uses a Base64
     This solution also has problems. The applica-          BasicDataSourceFactory class implements this          decoder that isn’t secure but adequately demon-
     tion is now responsible for either knowing the         method in the following way. First it typecasts       strates the concept. Finally the replace() method
     username and password or knowing the encryp-           the Object parameter to Reference. Then all of        removes the encrypted values and puts in the
     tion strategy. The application also needs to know      the name/value pairs are removed from the             decrypted values. When getObjectInstance(…)
     the real class implementing DataSource (in the         Reference object and set in a Properties object.      of the super class is called, it has the clear text
     case of Commons DBCP) so the username and              Finally, the Properties object is passed to the       passwords and is completely unaware that the
     password can be provided. This could make the          createDataSource(…) method where it’s as-             values in server.xml are actually encrypted.
     application not portable to another EE server. So      sumed the username and password exist in the              Using EncryptedDataSourceFactory is
     this is not an attractive solution either.             Properties object as clear text.                      simple. First drop the org.moss.jdj.jdbc-yyyy.
         The third solution is to take advantage of             To secure Tomcat database usernames               mm.dd.x.jar file into TOMCAT/server/lib. Next,
     Tomcat’s built-in extensibility. Inside the <Re-       and passwords, create a new class named               get a Base64 encoding of the username and
     sourceParams/> tag Tomcat offers the ability           EncryptedDataSourceFactory that extends Ba-           password. A simple Yahoo! search of “online
     to specify the fully qualified name of the Java         sicDataSourceFactory. This new class is going to      base64 encoder” will find sites that will do it. Fi-
     class that implements the javax.naming.spi.            override the getObjectInstance(…) method. The         nally, edit server.xml and replace the username
     ObjectFactory interface. This class is responsible     new method is implemented in the following            and password values with their corresponding
     for returning implementations of javax.sql.            way. First it will remove the encrypted username      Base64 equivalents and set the factory value to
     DataSource. By default Tomcat uses org.apache.         and passwords from the Reference object. Next,        org.moss.jdj.dbcp.EncryptedDataSourceFac-
     commons.dbcp.BasicDataSourceFactory and                it will decrypt them. Then it will put the de-        tory. Start up Tomcat and see it in action.
     this class requires <ResourceParams/> to have          crypted values into the Reference object. Finally         Using Tomcat’s built-in extensibility like this
     clear text username and password values. So            it will call the getObjectInstance(…) method of       is an attractive solution. It fulfills security audit
     why not create a class that extends BasicDa-           the super class so it can take care of creating the   requirements by removing clear text usernames
     taSourceFactory and is configured with an               DataSource. See the source code in Listing 3.         and passwords but it also lets applications be
     encrypted password instead? For the purposes           (Listing 3 can be downloaded from the online          coded to EE specs. Using this solution doesn’t
     of this article I’ll use a simple Base64 encoding      version of this article at http://java.sys-con.       put any unnecessary or unwanted responsi-
     but the concept can be easily extended to any          com)                                                  bility in applications. Applications can be devel-
     other method.                                              In the source code the “username” string of       oped to fulfill business requirements and don’t
         The source code for BasicDataSourceFactory         the setUsername() method and the “password”           have to worry about plumbing code like initial-
     has two important methods. They are:                   string of the setPassword() method refer to the       izing or shutting down a database connection
                                                            <name/> value of:                                     pool properly, maintaining a custom transac-
     public Object                                                                                                tion system to roll back on errors, or imple-
       getObjectInstance(                                   <parameter>                                           menting an encryption strategy. Plus, when
       Object o                                                  <name>username</name>                            the time comes to move away from Tomcat the
     , Name n                                                    <value>postgres_user</value>                     applications will be ready. The code in Listing
     , Context c                                                </parameter>                                      3 will be thrown away but small amounts of
     , Hashtable h)                                             <parameter>                                       throwaway code is much better than the effort
                                                                 <name>password</name>                            needed to go back and update applications.

      Listing 1                                                                            </parameter>
      <ResourceParams name=”jdbc/TestDB”>                                                  <parameter>
       <parameter>                                                                          <name>password</name>
         <name>factory</name>                                                               <value>postgres_pass</value>
         <value>                                                                           </parameter>
      org.apache.commons.dbcp.BasicDataSourceFactory                                      </ResourceParams>
       <parameter>                                                                        Listing 2
        <name>url</name>                                                                  DataSource
        <value>jdbc:postgresql://localhost/db</value>                                       ds = (DataSource)ctx.lookup(“java:comp/env/jdbc/SpiderMan”);
       <parameter>                                                                        org.apache.tomcat.dbcp.dbcp.BasicDataSource
        <name>driverClassName</name>                                                        bds = (org.apache.tomcat.dbcp.dbcp.BasicDataSource)ds;
       </parameter>                                                                       bds.setUsername(“MyUsername”);
       <parameter>                                                                        bds.setPassword(“MyPassword”);
        <value>postgres_user</value>                                                      return bds.getConnection();

30   June 2007                                                                                                                               

To top