Encrypting password for c3p0 ComboPooledDataSource - apache

I currently have a server.xml configuration which has the following in it
<Resource auth="Container"
description="DB Connection"
driverClass="oracle.jdbc.driver.OracleDriver"
maxPoolSize="40"
minPoolSize="2"
aquireIncrement="1"
name="jdbc/FOOBAR"
user="foo"
password="bar"
factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="path:to:db:port:db" />
I have a requirement to no longer allow the username/password to be in clear text in the server.xml file for obvious reasons.
I've read a bit online and came across How to Secure Tomcat Database Passwords for Java
Encrypt username and password for JNDI in Tomcat Server.xml and many other pages; however, I'm a bit stuck.
I first looked at extendind the BasicDataSourceFactory - but it seems that can't occur due to my using c3p0 CombinedPooledDataSource. I then looked at trying to create a c3p0 datasource wrapper by implementing PooledDataSource, Serializable and Referenceable but that didn't work either.
I read I could move the authentication to the server side by making auth="Container" => auth="Application". However, I'm not sure of how to implemet the rest of the pieces with my using Hibernate.
Any help would be great.

So, this will not be a high-security solution.
But an easy way around this is to make use of the fact that c3p0's "password" property is just a configurable c3p0 property, which can be set in a wide-variety of ways. So, you could create a c3p0.properties file and/or a c3p0-config.xml file, and set the password there. Alternatively, you could make sure that a System property c3p0.password is set when you run the JVM.
If you'll have multiple DataSources with different passwords, you'll need to use c3p0's named config feature, which means a c3p0-config.xml file.
c3p0 config (both c3p0.properties and c3p0-config.xml) files can be stuck at the top-level of a jar file in your application's effective CLASSPATH. (With tomcat, you have to be careful about distinctions between the web-app specific ClassLoader and more widely shared locations.) So, you can have your password embedded in a compressed jar file rather than a plain text file. Obviously, this is not secure: plaintext is just an "unzip" away. But it would prevent the password from being casually greppable and such.
Please see http://www.mchange.com/projects/c3p0/#configuration_files
Good luck!

Related

Tomcat, hide javax.net.ssl.keyStorePassword from -D options

The application installed on Tomcat (9.0.36.B.RELEASE) connects to an external source using SSL (in this case, IBM MQ). I therefore need to specify a truststore, and password for this truststore.
I got it to work adding this to the JVM_OPTS in setenv.sh:
-Djavax.net.ssl.trustStore=/opt/apps/certs/myapplication.truststore
-Djavax.net.ssl.trustStorePassword=TRUSTSTORE-PASSWORD
-Djavax.net.ssl.keyStore=/opt/apps/certs/myapplication.keystore
-Djavax.net.ssl.keyStorePassword=KEYSTORE-PASSWORD
Classic issue with this, the passwords are visible when I do ps -ef|grep java (runs on RHEL).
I have seen a couple suggestions on how to do this (like Hiding plain text password in JVM startup argumnets. " ps -ef | grep 'javax.net.ssl.keyStorePassword'"). But these change/add code or configuration in the WAR file.
I am looking for a "tomcat" solution. Is there a way to to this within the confines of Tomcat. Changes to the WAR file are difficult to implement, as the application comes from a vendor.
Note: this is not for a connector configuration in web.xml since that would only setup SSL for incoming connections. Here the application is making connections to an external system (so outbound from Tomcat's perspective).
You can add additional properties to $CATALINA_BASE/conf/catalina.properties and they will be sourced during Tomcat's startup. As you are certainly aware, system properties are global to the JVM, so there is no way to restrict this configuration to a single application only: the entire Tomcat server will be affected.
Almost all Java system properties can by set this way, with a few exceptions:
catalina.base and catalina.home (obviously),
the configuration for Tomcat logging,
the configuration for JMX and other tools that start before user code.
Attention: You must check whether the VersionLoggerListener (defined in server.xml) does not have logProps="true", otherwise the values of system properties will be logged. By default only the JVM arguments are logged.

Hide or disable Tomcat command line arguments logging

Our application server (Apache Tomcat Plume) that use jta-managed data source through tomee.xml file should access database server just in secure (HTTPS) mode with two way ssl or client authentication.
So we have to put keystore and truststore plain passwords into setenv.sh or other places in row format. (I m not sure that is the first and last method to do that?) and what happens is tomcat logging mechanism log all these secret information in plain format into log files like catalina.out.
That what (locating raw passwords in config files) is we do not want. Actually we must ( although it s not appear a big threaten while user have access to files, could find real password atleast), encrypt password and use it in environment variables.
Central Question
In other word, how can we set jvm properties and environment variables in encrypted mode?
Re: Hide or disable Tomcat command line arguments logging (the title of this question)
This logging is done by VersionLoggerListener it is possible to configure it, or just remove it from configuration (server.xml).
Re: plaintext passwords handling
This is covered in Tomcat FAQ.
A Vault can be used to store secrets.

How to manage database credentials for mule proejct

I am using database connector component, with vault component to store the database credentials. Now as per the documentation of both components i have created different properties file for each environment to store the encrypted credentials for diff env.
Following is the structure of my mule project
Now the problem with this structure is that i have to build new deployable zip file whenever i have to update the database credentials for any environment.
I need a solution where i can keep all credentials encrypted and centralized and i don't have to create a build every time after updated the credentials, We can afford to restart the server, but building new zip and deploying is really cumbersome.
Second problem we have this approach is a developer needs to know the production db to update it in properties file, this is also a security issue.
Please suggest alternate approach for credentials management for mule projects.
I'm going to recommend you do NOT try to change the secure solution provided to you by MuleSoft. To alleviate the need for packaging and deployment, you would have to extract the properties files outside of the deployment and this would be a huge risk. Regardless of where you store the property files within the deployment if you change the files, you have to package and re-deploy. I see the only solution to your problem as moving the files outside of the deployment and securely storing them. Mule has provided a solution while it may be cumbersome, they are securing these files first with encryption and secondly within the server container. You can move out the property files but you have to provide a custom implementation and you will be assuming great risk to your protected resources.
Set a VM arguement e.g. environment.type=local for local machine on your anypoint studio.
Read this variable in wherever you are reading your properties file in a way that environment type is read dynamically such as below.
" location="classpath:properties/sample-app-${environment.type}.properties" doc:name="Secure Property Placeholder"/>
In order to set the environment type on your production server(or wherever you are using mule runtime), open \conf\wrapper.conf and add the arguement wrapper.java.additional.=-Dserver.type=production. If you already have any property in this file, you may need to set the value of n appropriately. For example 13 or 14.
This way you don't need to generate different deployment artefacts for different environment because correct properties file is picked by using environment specific VM arguement.

Getting configuration strings from Weblogic

This question is related to Weblogic 12c.
I have an EAR file that I want to deploy in various environments (dev, QA, pre-prod and prod). However, my application requires a username and a password (to connect to another server) and they're not the same across the four environments. I don't want to package 4 different property files in 4 different EAR files. I want a single generic EAR file. Beside, I don't want to handle the prod password during packaging.
Ideally, I'd like the admin of each environment to provide the appropriate username nad password for the environment. Unlike Tomcat, Jetty or JBoss(?), I think it's not possible for a WebLogic Admin to specify this information in a way that it will become available under the java:comp/env JNDI context.
How can an application obtain some admin-defined configuration strings from Weblogic?
BTW, it's not a username/password for a JDBC connection.
From what I understand, you need to change parameters based on the environment you are using right?
If you would like to override parameterss on the fly you can use WebLogic deployment plan concept.
Did you mean that you need to provide username/password to start-up the application?
If so, you may accomplish that by creating a script with WLST http://docs.oracle.com/cd/E15051_01/wls/docs103/config_scripting/using_WLST.html
As far as I know, the WebLogic way is to
Define your username/password as env-entry in the deployment descriptor
Deploy your application together with the plan.mxl whereas each environment admin maintains his own envrionemnt-specific version of the plan.xml
That way you get them into /comp/env/config
More details here: http://docs.oracle.com/cd/E11035_01/wls100/deployment/config.html
Only drawback known to me: plan.xml will always contain the unencrypted password but as the admin knows the password anyway and this is "his" file on "his" maschine that should be fine.

How do you create "Aliases" in Apache Tomcat?

I am working on a web application that allows users to upload attachments. These attachments are stored on a different drive than that of the web application. How can I create an alias (equivalent to Apache HTTP server's aliases) to this drive so that users can download these attachments?
Currently I am creating a context file and dumping it in CATALINA_HOME/conf/Catalina/localhost, but it gets randomly deleted every so often. The context file is named attachments.xml and the contents are shown below. I have also read about virtual hosts, but if I understand correctly, then a virtual host is not what I am looking for. I am using version 6.0.18 of Apache Tomcat.
attachments.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase = "e:\uploads\attachments"
reloadable = "true"
crossContext = "true">
</Context>
I spent a lot more time researching this and found a solution that solves the random deletion of the context files. I found this excerpt on Apache's website under the host configuration section:
You can nest one or more Context
elements inside this Host element,
each representing a different web
application associated with this
virtual host.
The virtual hosts are stored in the server.xml file located at CATALINA_HOME\conf. Tomcat comes configured with localhost as the default host. So, if we add the contents of attachments.xml from the first post, we get the following:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/attachments"
docBase="e:\uploads\attachments"
reloadable="true"
crossContext="true" />
</Host>
This is as close as one can get to defining aliases similar to Apache's HTTP server, I think.
There are multiple options.
Use Apache as frontend, delegating to tomcat by mod_jk or mod_proxy
Provide a download servlet in your own application, serving the requested file
Make the directory that you want tomcat to deliver a web application
each has some drawbacks and some advantages. I strongly prefer the first solution for multiple reasons:
My main reasons apply to unixoid systems, which you are obviously not talking about: Only root can bind ports lower than 1024, e.g. 80. Therefor tomcat would need to run as root (I know that there are mechanics to allow users to bind to low ports, but I've never gotten to use them). Apache is usually started as root but drops these privileges as soon as port 80 is bound.
Apache is said to be a lot better in serving static resources than tomcat (I've never measured it, but find it hard to believe the contrary)
You obviously know how to create aliases in apache - it would be trivial to do so.
About the download servlet:
This way you'd have a servlet serving your static resources, which you might bind to the urls "/download/*" (e.g. in the application that also handles file uploads) You'd gain:
You need to configure the directory where your files are stored only once
If you need you might easily implement permission checks (e.g. login required for downloading)
You need to deploy only one completely selfcontained application.
The download servlet is trivial - find the file, set it's name and filetype in the output stream and stream it byte by byte, then close the output stream (be sure to handle attacking file names like "/download/../../../../etc/passwd" or "/download/C:/WINDOWS/someimportantfile.xxx"), e.g. by using the java.io.File constructor that gets the base directory as a separate parameter.
The third option has some severe drawbacks and opens you for attacks if you don't take special care of them:
Tomcat does not serve directories, but webapps. Therefor "E:/upload/attachments" would need at least a directory named "WEB-INF", containing "web.xml". Take care to not provide write access to this directory and file from the uploading web application. With this provision you might let tomcat serve the directory.
However: Configure the contained web.xml to not serve "*.jsp" as a jsp, otherwise tomcat would not just deliver jsp files but execute them. Imagine someone uploading "index.jsp" with <% System.exit(0); %> or more malicious content.
One additional thought: You don't need the extra crosscontext="true". This would imply that the webapplication that you deploy just to serve your files has access to other webapplications, e.g. is able to manage them or access their private data. Usually you don't need that at all, in the case of your question you definitely don't want that.
See the initial part of my newer question for ways to do this by editing the context.xml file
How do I add aliases to a Servlet Context in java?.
According to several people now, it is no longer necessary (2012: Tomcat 6 or 7) to use Apache for performance reasons over Tomcat for serving static content.