Monday, September 26, 2005

SOX - Security Policy

I was asked to solve an interesting problem today. The problem is to hide the database password from everyone but the production system that uses it. The db account information is currently stored in properties files. The properties files are in plain view on the production boxes, along with the version control system, etc... The goal is to have the password reside in a single spot, and in such a way, where it is still accessible by a couple of production system across the globe, but is not known by anyone but the senior manager and the dba. hmmmm. It should also be possible to change the password by modifying it in one spot, and have every system automatically start using the new password. hmmm again.

I thought about this for a bit, and came up with using public/private key cryptography. The idea is to put a private key on each machine that needs to use the production db account. The private key will only be accessible by the system account. The system properties file will contain a guest database account that will have access to a password table. The password table will contain a crypted account information that was encrypted by the dba or the manager using the associated public key. So, the dba crypts the db account using the public key, writes the crypto into the table. Each system has a guest account to read the table and has access to the private key which will decrypt the account. The system will then drop the guest connection, and re-create db pool using the decrypted production db account. The solution sounds good, but has a major flaw. It requires a guest account on a production database system. The guest account might not sound very dangerous, but it allows the hooligan to start from within the database rather than have to figure out how to even connect to it.

2 comments:

Anonymous said...

You can refine this by :

- getting a separate system to handout the encrypted passwords rather than using a guest database account

- getting each system to identify itself before giving it any information

For example,

1. Remove the guest database account

2. Create a new database account ( e.g. 'passwordhelper' ) which only has access to a stored procedure to retrieve encrypted passwords

3. Setup a small ( internal-use) web service to serve up the encrypted passwords. The web service is the sole user of the passwordhelper account. To use this web service, each system must identify itself. This could either by done by using https with client-side identification or by using the system's private key to encrypt some information handed out by the web service.

To refine it even further, you may consider not handing out the password at all but getting the web service to return a serialized JDBC connection object ( assuming your systems are in Java ).

Vadim said...

The unfortunate problem is that in this particular company the developers are also the support people and the management does not trust the developers. In other words, the management does not trust the actual people supporting the production systems. The other unfortunate thing is that the production systems require almost constant active support. So, in summary we have a group of people who have access to the production database, production machine, and production source code and use it daily. They are able to write any code and run it within any system with absolutely no oversite. My requirement is to build a system that will protect the production system passwords from these people.

The solution I've finally came up with has encrypted passwords stored in the database. The tables can only be accessed by a single secure account whose password is only known by the manager. When the password system is first started, the manager is required to login and initilize the system with the password. On re-start the password is lost. In this case I am assuming or hoping that rollout of this system or any tempering with this system is carefully monitored. (probably not). Anyways, the system knows all passwords and uses a basic encryption scheme. The server knows who uses each password, and dumps the password in a file on that server in a location readable only by the prod unix account. Simple, many holes, but no body cared. This whole project was created so that someone can put a check next to an entry on security on a SOX report.

I wanted to tighten up the architecture. For example, why should the unix admin know a db account.

I like your ideas on the web-service. The problem is that the other party is untrusted. This can probably be mitigated, but again, I was overruled in favor of something quick, simple, and sort of secure.
Also, very interesting on the serialized JDBC connection, alas, not all are java. Ironically, most are ksh.

Anyways, nice post, thanks.