Retrieve ColdFusion datasource passwords

Mike Callahan
5 min readOct 6, 2016

--

Have you ever forgotten your datasource password? Passwords are encrypted and stored but fortunately there is a way to recover them. ColdFusion’s ServiceFactory provides a bunch of information including details about your datasources. You can retrieve things like datasource name, driver and driver class, connection properties, username, password, and which privileges are activated (select, insert, update, delete, grant, drop, stored procedures, etc.). There’s a whole host of things you can access from the ServiceFactory. To see what’s available just grab the ServiceFactory and dump it out like this:

<cfset sf = CreateObject("java",coldfusion.server.ServiceFactory")> 
<cfdump var="#sf#">

You’ll see the getDataSourceService() listed in the dump. Inside getDataSourceService() is a method called getDataSources(). To see what information you can retrieve using getDataSources() you will need to first authenticate yourself using your CF admin password. Then you can dump the results of the method and see what all information you have available.

<!--- replace "yourPassword"  with your CF Admin password---> 
<cfset authenticate=createObject("component","CFIDE.adminapi.administrator").login("yourPassword")>
<cfset sf = CreateObject("java", "coldfusion.server.ServiceFactory")>
<cfdump var="#sf.DataSourceService.getDatasources()#" expand="true">

This is all good, however passwords are encrypted and not available in plain text. There’s a solution for that too. The first thing to know is that datasource passwords are encrypted using an encryption algotithm and a unique seed. In CF10 the seed and algorithm information is stored in \ColdFusion10\cfusion\lib in a file called seed.properties.

Here you will find the “seed” and “algorithm” you will need in order to decrypt your passwords. Prior to CF10 the seed and agorithm are fixed values and are “0yJ!@1$r8p0L@r1$6yJ!@1rj” and “DESede” respectively. For CF10 and beyond you will need to retrieve these values from the seed.properties file.

seed.properties

Now let’s have a look at some code you can write to help retrieve your passwords. The first step is to find out what version of ColdFusion we’re running.

<cfset license=createobject("java","coldfusion.server.ServiceFactory").LicenseService.getMajorVersion()>

In order to access the datasource passwords from the service factory you will need to make sure to authenticate yourself with a valid CF Admin password. You can do this with a form and input your password. To keep things simple you can have the form’s action submit to the same page by using #cgi.script_name# in the value for the action attribute.

<form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post"> 
Enter the CF Admin Password: <input type="password" name="adminPassword"><input type="submit" value="Submit">
</form>
Here’s the result of the above code

Now, the way to validate the password for CF10 is:

<form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post"> 
Enter the Seed: <input type="text" name="seed"><br>
Enter the Algorithm: <input type="text" name="algorithm">
<input type="submit" value="Submit">
</form>
Here’s the form for the seed and algorithm

When running the code you will copy and past the seed and algorithm values from the seed.properties file.

seed.properties

Now let’s go to the ServiceFactory and get the datasource information.

<cfset variables.datasourceObject=createobject("java","coldfusion.server.ServiceFactory").getDatasourceService().getDatasources()>

Almost done! The datasourceObject you created is a collection of all of your datasources. Let’s loop through the collection and output the results. In order to see the password you will need to decrypt the password value pulled from the ServiceFactory. This is where you need the seed and algorithm values. The last piece looks something like this.

<table border="1" cellpadding="5" cellspacing="0"> 
<tr bgcolor="c0c0c0">
<th>Datasource</th>
<th>UserName</th>
<th>Password</th>
</tr>
<!--- Loop through datasources --->
<cfloop collection="#variables.datasourceObject#" item="variables.datasource">
<cfif len(variables.datasourceObject[variables.datasource]["password"])>
<!--- Set username --->
<cfset variables.username = variables.datasourceObject[variables.datasource]["username"]>
<!--- Set decrypted password - Pre CF10 versions --->
<cfset variables.decryptedPassword = Decrypt(variables.datasourceObject[variables.datasource]["password"],generate3DesKey("#form.seed#"),"#form.algorithm#","Base64")>
<!--- Output datasource information --->
<cfoutput>
<tr>
<td>#variables.datasource#</td>
<td>#variables.username#</td>
<td>#variables.decryptedPassword#</td>
</tr>
</cfoutput>
</cfif>
</cfloop>
</table>
results from the above code

Putting it all together with a little validation on the forms and accomodating ColdFusion versions prior to CF10, here’s the full code that should work quite nicely.

<h1>ColdFusion Datasources</h1> 
<cfset license=createobject("java","coldfusion.server.ServiceFactory").LicenseService.getMajorVersion()>
<cfset form.license=variables.license>

<cfif NOT isdefined("form.adminpassword") OR (isdefined("form.adminpassword") AND NOT len(form.adminpassword))>
<cfif isdefined("form.adminpassword") AND NOT len(form.adminpassword)>
<font color="#FF0000">The password cannot be empty!</font>
<cfelse>
<br>
</cfif>
<form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post">
Enter the CF Admin Password: <input type="password" name="adminPassword"><input type="submit" value="Submit">
</form><cfabort>
<cfelse>
<cfset adminauth=createObject('component','CFIDE.adminapi.administrator').login('#form.adminpassword#')>
<cfif NOT adminauth>
<font color="#FF0000">The password was incorrect!</font><br>
<form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post">
Enter the CF Admin Password: <input type="password" name="adminPassword"><input type="submit" value="Submit">
</form><cfabort>
</cfif>
</cfif>
<cfif isdefined("form.adminpassword")>
<cfoutput>ColdFusion Verion: #variables.license#<br><br></cfoutput>
<cfif isDefined("variables.license") AND variables.license LT "10">
<!--- Create datasource object --->
<cfset variables.datasourceObject=createobject("java","coldfusion.server.ServiceFactory").getDatasourceService().getDatasources()>
<table border="1" cellpadding="5" cellspacing="0">
<tr bgcolor="c0c0c0">
<th>Datasource</th>
<th>UserName</th>
<th>Password</th>
</tr>
<!--- Loop through datasources --->
<cfloop collection="#variables.datasourceObject#" item="variables.datasource">
<cfif len(variables.datasourceObject[variables.datasource]["password"])>
<!--- Set username --->
<cfset variables.username = variables.datasourceObject[variables.datasource]["username"]>
<!--- Set decrypted password - Pre CF10 versions --->
<cfset variables.decryptedPassword = Decrypt(variables.datasourceObject[variables.datasource]["password"],generate3DesKey("0yJ!@1$r8p0L@r1$6yJ!@1rj"),"DESede","Base64")>
<!--- Output datasource information --->
<cfoutput>
<tr>
<td>#variables.datasource#</td>
<td>#variables.username#</td>
<td>#variables.decryptedPassword#</td>
</tr>
</cfoutput>
</cfif>
</cfloop>
</table>
<cfelseif NOT isDefined("form.seed") OR NOT isDefined("form.algorithm")>
<form action="<cfoutput>#cgi.script_name#</cfoutput>" method="post">
<input type="Hidden" name="adminPassword" value="<cfoutput>#form.adminPassword#</cfoutput>">
<input type="Hidden" name="license" value="<cfoutput>#form.license#</cfoutput>">
Enter the Seed: <input type="text" name="seed"><br>
Enter the Algorithm: <input type="text" name="algorithm">
<input type="submit" value="Submit">
</form>
<cfelse>
<!--- Create datasource object --->
<cfset variables.datasourceObject=createobject("java","coldfusion.server.ServiceFactory").getDatasourceService().getDatasources()>
<table border="1" cellpadding="5" cellspacing="0">
<tr bgcolor="c0c0c0">
<th>Datasource</th>
<th>UserName</th>
<th>Password</th>
</tr>
<!--- Loop through datasources --->
<cfloop collection="#variables.datasourceObject#" item="variables.datasource">
<cfif len(variables.datasourceObject[variables.datasource]["password"])>
<!--- Set username --->
<cfset variables.username = variables.datasourceObject[variables.datasource]["username"]>
<!--- Set decrypted password - Pre CF10 versions --->
<cfset variables.decryptedPassword = Decrypt(variables.datasourceObject[variables.datasource]["password"],generate3DesKey("#form.seed#"),"#form.algorithm#","Base64")>
<!--- Output datasource information --->
<cfoutput>
<tr>
<td>#variables.datasource#</td>
<td>#variables.username#</td>
<td>#variables.decryptedPassword#</td>
</tr>
</cfoutput>
</cfif>
</cfloop>
</table>
</cfif>
</cfif>

You can retrieve a lot of great information from the ServiceFactory. Being able to retrieve datasource passwords is something handy to have in your back pocket because I guarantee sooner or later you will forget a password or two.

--

--

Mike Callahan

Building stuff on the web and mobile devices and sharing with others.