Under attack

April 23, 2007 · By Gert Franz · No Comments

There are some security concerns about using datasources that I would like to share with you. It is concerning the general usage of datasources, no matter which CFML engine you use.One of the first things I would try as a potential website hacker is to check whether SQL injection does work. Regardless of the outcome, databases allmost allways are a good target in CFML. This came to me one evening last week when I presented Railo to a new customer and he asked me whether it was possible to join two different databases within one query.
Just imagine the following situation. You have hosted a website at a larger CFML hoster and your website is storing some important data in your MSSQL database. Now you define a datasource user with absolutely no rights on the database and you use username and password in every query.
This is the way it is supposed to be in a CFML hosting area. Just in my special case an other datasource has been registered for test purposes with the "sa" username (or maybe one with similar rights). It was supposed to be just a test datasource.
Since an other user (let's call him attacker) might have the right to upload files to his root directory he coul upload a file containing the following code:
<cfset oDsnService = createObject("java", "coldfusion.server.ServiceFactory").getDataSourceService()>
   <cfset stDatasources = oDsnService.getDatasources()>
   
or for Railo:

   <cfadmin action="getDatasources" type="web" password="railoWebAdminPassword" returnVariable="datasources">
With this knowledge the following code could be executed:
<cfloop collection="#stDatasources#" item="dsn">
      <cftry>
         <cfquery name="getObjects" datasource="#stDatasources[dsn]#">
            SELECT * from [master].[dbo].[sysdatabases]
         </cfquery>
         <cfif getObjects.RecordCount neq 0>
            This datasource (#stDatasources[dsn]#) is vulnerable<br>
         </cfif>
         <cfcatch type="Database">
            This datasource (#stDatasources[dsn]#) is secure<br>
         </cfcatch>
      </cftry>
   </cfloop>

Railo asks you for a web password. And in addition to that it only retrieves the datasources of your local web. Whereas other engines might retrieve all defined datasources of the current instance. I'm not sure if it asks for a password though. There was a security upgrade some weeks ago, but I am not sure whether it concerned the retreival of datasources as well.
Now, if the upper code delivers one or more vulnerable datasources then you could do something like this (even if the datasource defined for the attacker is purposed for entirely different database).
<cfquery name="getOtherData" datasource="myDatasource">
      SELECT * from [otherDatabase].[dbo].customers
   </cfquery>
   <cfdump var="#getOtherData#" label="getOtherData">
or for Railo:
   <cfdump eval=getOtherData>
The explanation is quite simple. For a datasource definition not the related database is relevant, but the database username you define. Therefor I have some handy hints for the definition of your datasource in a CFML hosting environment:
  • Allways define datasources with a username that has only rights for it's own database.
  • Define the datasource with readonly rights and use the attributes username and password in your queries and storedproc tags
  • Reconsider defining a datasource with an user that has access to more than one database
  • NEVER define a datasource with the sa user in a hosting environment
An other potential attack source can be the definition of datasources with more than readonly rights. Since some engines do not differ between templates that are called from different webroots they can not restrict the usage of this datasource. So our attack user could create a template with the following code (having retrieved the datasource name from the code above):
<cfquery name="getTables" datasource="notMyDatasource">
      SELECT * from SysObjects WHERE XType = 'U'
   </cfquery>
   <cfdump eval=getTables>
   ...
In some engines you either have to use things like sandbox security in order to forbid the usage of certain datasources or you have to install a new instance of the engine.
Railo does bundle all definitions to its web. So for web A you have 2 datasources and for web B you have other ones. The code inside web A has absolutely no access to the datasources (or other resources) of web B. So the above tips for the definition of datasources are valid for one single web. But there the potential risk is quite limited.
Allthough if you define a datasource with the "sa" user, the database server is completely vulnerable. No obstacle for a "drop database" anymore.

Tags: Features · Railo 1.1 · Security

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

Leave a Comment

Leave this field empty: