2

I have an app server hosting a CakePHP app and a database server hosting the databases. The servers are physically separate. The databases contain encrypted sensitive information. The encryption keys for the encrypted data are also stored in the database (which are themselves encrypted). The keys are decrypted by the app for use in decrypting the database information.

I am under the impression that if someone were to compromise the database server and steal the databases they would not be able to decrypt the data since the app, (which is on a different server), has the encryption key. The problem arrises if someone is able to compromise the app server. If the app server becomes compromised, the database connection information is stored directly in the CakePHP app as follows:

public $default = array(

  'datasource' => 'Database/Mysql',
  'persistent' => false,
  'host' => 'xxx.xxx.xxx.xxx',
  'login' => 'login',
  'password' => 'password',
  'database' => 'database',
  'prefix' => '',
  //'encoding' => 'utf8',

);

Is there a way to store this connection information in a more secure fashion or is this just a matter of knowing that if the app is compromised, the database is also compromised? Are there things I can do to mitigate the chances of this type of compromise that I may not have thought of? Thank you in advance!

3

If the application is compromised, the database is compromised even if you can conceal the credentials. The DB credentials should only be valid from the application server's IP address and if they have compromised the application server that much, they can simply alter the application code to do whatever they want if you did somehow manage to protect the credentials.

The key thing is to make sure that the credentials only work from the server and that the user that the application uses can only impact the application itself in the ways the application needs to interact with the DB.

Really, it is very hard to conceal the credentials any better anyway. You can use something like a TPM, but then the application needs a way to get access to the TPM. Unless you don't give the application authorization without the user providing credentials for the DB itself, then you have to store them.

Depending on how the sensitive data is accessed, you may also be able to use user based encryption. With user based encryption, you use the user's password to derive a key which is used to encrypt a secure key. That secure key is then used to unlock a keyring which contains keys for accessing any records the user has access to. Since the user's keyring is only accessible when the user is logged in, it reduces the threat of an offline compromise where both the application server and DB server are compromised.

This does put some limits on what can be done while the user isn't logged in, though you can have a sproc that has access to do some decryption operations using a master key ring that only is available in the DB server, but you'd have to be very careful to lock that functionality down tight to prevent it being abused. (Rate limits on custom sprocs for each type of query you need against the secured data for example.)

| improve this answer | |
  • Just to expand on 'ways the application needs to interact with the DB' - this means no direct DML (SELECT, INSERT REPLACE, UPDATE etc) - all access should be mediated by stored procedures on the DBMS - in the case of MySQL, susch procedures (and functions) should be declared to run with the privilege of the definer, not the user. – symcbean Feb 6 '14 at 14:07
  • @symcbean - that's the most intense level of security, though it isn't needed in every case. The main priority for any application should be to ensure the compromise doesn't spread (to other systems). How much the application needs to be self-protecting is an exercise left to the developer based on the needs for the application. Ensuring that the SQL user can't misbehave even when compromised is nice for high security, but putting all your logic in to sprocs and effectively coding in the DB isn't always a worthwhile trade off, particularly if damaging enough sprocs have to exist anyway. – AJ Henderson Feb 6 '14 at 14:18
  • If the attacker has local server execute access and db credentials, you are pretty much hosed no matter what unless the entire application logic is written in SQL. You are going to have to restore from backup either way since the state is compromised. If they are able to delete * vs being able to make 1000 delete sproc calls isn't a significant difference in most cases. – AJ Henderson Feb 6 '14 at 14:21
  • If the database is storing encrypted data which can only be decrypted at the application tier (thereby effectively disabling most of the functionality in the database for indexing) I humbly suggest that JadedCurve is looking to employ any and every security measure up to, and including a tin-foil hat. – symcbean Feb 6 '14 at 14:26
  • @symcbean - ah, true, I admit I had only glanced over the highlights of the question. I'd also add then that user encryption keys, protected by password derived keys should be used to store encryption keys that the application server can't access itself if you really want the tin foil hat. – AJ Henderson Feb 6 '14 at 14:29
1

Use environmental variables. You can store the database credentials as environmental variables in your server, for example in the apache or nginx configuration for your application. In that case if your code is compromised, then the attacker would also need to breach into the webserver configuration files which is another level of security. There are plugins for making this work in CakePHP, for example take a look at this application template:

https://github.com/FriendsOfCake/app-template#application-configuration

In the example they recommend setting the env variables inside a file, but I recommend doing it directly on the webserver.

| improve this answer | |
  • Wanted to add, if the attacker has access to your server, then there is little you can do, this at least secures you against accidental code share or leak – José Lorenzo Rodríguez Feb 5 '14 at 22:24
0

It's best to use environment variables in this case. I use them all of the time in Django development. With correct permissions set on the server itself it can mitigate a direct database compromise.

http://www.fullybaked.co.uk/articles/add-environment-variables-to-cakephp

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.