tags:

views:

880

answers:

22

Hi everyone,

Long time listener, first time caller.

'Say you have a database table that is responsible for logging user activity. The integrity of this log is important, so you want to be able to detect if someone has modified any data from the table. To make things more interesting, also consider the fact that your system may be operated by an evil SQL admin who has complete control over this wretched system. yikes...

How would you safeguard your data?

How would you detect if someone has tampered with your data?

You have unlimited tools at your disposal. (i.e. hashing, encrypting, etc.)

+1  A: 

Set up your system to write the logging data to a remote system the evil SQL admin does not have control over. This will not prevent said admin from removing or tampering with your logging program, but it will prevent him from modifying them after the fact.

Paul McMillan
+2  A: 

You could use triggers whereby you audit inserts, updates, and deletes. Now, if the "evil SQL admin" disables triggers then you have some more difficult issues. I would not allow an evil admin to have complete control over the system if I wanted to safeguard my data.

BobbyShaftoe
Reading that book now brilliant!
Byron Whitlock
I disagree, as an evil Admin the first thing I'd look for would be triggers.
joshperry
That's a pretty hilarious statement. Obviously no one would intentionally allow a malicious user, still less a malicious admin. The problem is, you can't really REALLY trust anyone, so how do you mitigate the inevitable risk?
Satanicpuppy
@joshperry, well the only thing is that the problem with triggers here is the same problem almost every other answer has. If someone has complete control then by definition they have complete control over that system. You could, at least, use triggers to send auditing information a remote server that the evil admin does not have access to.
BobbyShaftoe
+1  A: 

This is a common data security issue. The simple answer is- if you are in a situation where one single "evil SQL admin" has access to your whole environment, you have no way to protect your data.

A common practice for mission-critical data is to log to multiple backups and protect by ensuring that no single person has permissions.

Dave Swersky
Unfortunately most corporate espionage is perpetrated by internal actors. But I think what you meant was to have many eyes on the situation to prevent mischief. Unfortunately without physically separated keys (like in a nuclear silo) a `drop database` only takes a fraction of a second. I think this speaks volumes for following least access and single responsibility principles, and really knowing the people that run your business, they ARE your business.
joshperry
Separate "keys" (literal or figurative) is the way I've most commonly seen to protect against internal sabotage. You can't always prevent disaster, but you can arrange things such that a conspiracy between at least two people is required to wreak havok.
Dave Swersky
+11  A: 

If the "evil admin" has no access to the application that populates the database, a extra column on each table consisting of a cryptographic signature for the rest of the columns will do the job. The "no access" condition is needed such that they can't just extract your private key and sign their fake data.

Edit: Ah, as the commenters point out, I didn't consider the admin just deleting a row. For this, you'll need one extra row with a cryptographically signed row count that you update each time (or a signed hash of the rest of the table content, or last access time, or whatever indicator you choose).

Adam Wright
This does not take into account the evil admin just deleting a row.
joshperry
@joshperry - exactly my thoughts.
Glenn T.
How do you keep the evil admin from having access to the private key used to sign the data? It must be stored somewhere on the database system to sign the data in the first place...
billmcc
billmcc - I'm assuming that there is an application separate from the database generating the data.
Adam Wright
+3  A: 

Create a shadow table that hashes every filed with a key/salt only you and the application knows about. If you want to check for data tampering, rehash the user table and compare against the shadow table.

Byron Whitlock
+5  A: 

If you really want to be secure Use - Write once Read Many Media for that table.

Dani
I actually still pay for tractor-feed greenbar paper and a dot-matrix printer for a log on one of our primary financial systems. Obviously I can't log with a lot of detail, but I can log write transactions, and I can log user access. Sometimes the low tech solution is the best.
Satanicpuppy
@Satanicpuppy: That could be real useful for an audit, and one reason why I never wanted to be an auditor.
David Thornley
The auditors wet their pants when I pull out the paper logs. They don't even really look at them, but the boxes of paper SCREAM due diligence.
Satanicpuppy
Nothing says old-school DP like boxes of green bar paper. For additional aesthetic effect, you could add a few boxes of punch cards.
David Thornley
The sign out in front of my office still says DP ("Data Processing", for all you damn whippersnappers).
Satanicpuppy
Whats to stop you Dogbert admin editing the file and printing it off on the green lined parper? (Actually seen this done by an operator truing to covering up his mistakes!).
James Anderson
it is not ecological. how many paper you need to waist for 1 WORM HD ?
Dani
The paper log, in my case, isn't a copy of the LOG, it's a copy of the console. The data from the logs is different. Anyway, it runs out on greenbar, so you can't really just pull a page out of the middle...It's all attached. And the place where it sits isn't readily accessible. Still, it's possible someone could fudge it. All you can do is try.
Satanicpuppy
+1  A: 

If your application is always running you could start up a transaction on the database and don't release it until your app closes... that way nothing can ever even view the table but your app...

Also yes, encrypt all of the text string data that goes in and out of your program if you have time to do that...

I like BobbyShaftoe's answer as well... take it a bit further though, see if you can get the trigger to "sleep" or something so after a few minutes all records go back to what they were... so our evil Admin thinks he made changes, but they will just get reverted.

Jrud
Inventive, but the evil admin can terminate connections pretty easily with sp_kill.
joshperry
Agree @JP again, with the additional note that a never-ending transaction is indistinguishable from a virus, as far as your server performance is concerned.
Satanicpuppy
IIRC, Oracle 9i databases could be set to drop transactions after enough time. New transactions need a consistent view of the database, which means not counting any transactions that haven't been committed yet. Moreover, the system has to be able to roll everything back if the transaction is dropped. The redo logs go back only so far, and when they drop off (IIRC) Oracle has to either drop or commit.
David Thornley
well how about a service app that is constantly holding and re-grabbing locks on the database when neccessary unless the main app is running? (very virus-like)
Jrud
+21  A: 

If you really must detect that tampering has occurred, then add a checksum field to the table. The checksum for each new row must include the checksum of the prior row. Then to verify the content, walk through the dataset computing the checksum as you move forward. If the calculated checksum doesnt match the value in the table then some value has been tampered.

-Mike

MikeMontana
I like this answer, but if the evil admin knows the hashing function he could remove a row at random and rehash all rows. Now combine this row-chained hash with a intra row signature to validate that no column has been tampered with and I think you have a winner.
joshperry
Luckily you do not have to prevent tampering, I would say this really goes a long way toward detecting it.
jphofmann
This doesn't prevent the "evil admin" from changing whatever data, then recomputing the checksum for all rows (unless you use a checksum secured with some private data, such as a cryptographic signature).
Adam Wright
Evil admin can recalculate the checksums of all records after making his changes unless the checksum contains a salt not known to the admin.
Ztranger
Agree with Joshperry. My workaround to that would be to double log (security through obscurity at its finest), or to include some third party rock-n-roll in the hash: if the admin doesn't have access to the third party data, he can't recreate the hashes. Or you could add in an intentional error every so often, an error that wouldn't be replicated if the admin was recreating everything. In the end though, if they have full access, they can circumvent any measure...They don't even have to be creative, they can just nuke the whole log and leave you with nothing.
Satanicpuppy
@MikeMonta - also consider the fact that the sys admin has the ability to backup and restore data... yikes, this guy is sneaky!
Glenn T.
Sorry - but if you *really* have an evil admin, you have far bigger problems than this one. Trying to over-complexify the tamper detection to thwart this hypothetical evil admin is probably less efective than just implementing a simple tamper detection system. It all depends on WHO you think you are going to catch, I guess.
Huntrods
@Adam, @Ztranger: If the evil admin's scope is restricted to the DB server, then the checksum code and any associated keys can reside in the application, safely out of reach.
Annabelle
A: 

As well as triggers for auditing, checksums etc, you could look at replicating the database to another slave db - with nobody able to perform any actions directly on it.

You still have the risk of someone messing with the triggers etc, but it would be extremely visible when they were messed with, so you'd be able to detect at which point the replication was broken.

Hippyjim
If nobody can perform any actions on it, how does it replicate? If it does so only at intervals, the evil DBA can do what he likes between replication times.
David Thornley
replication is pretty much instantaneous - and you can't perform write actions on the slave db without breaking the replication - a simple replication status checker can set up an alert to show when that's happened, so you have a "tamper alarm". Of course, the only real solution is to not hire an evil DBA - check his facebook and union membership credentials - if it says "I'm evil" anywhere...don't hire him.
Hippyjim
@David Thornley: I'm not being clear. You're apparently talking about replicating it at some interval, so you can check previous versions. This makes it difficult for the evil DBA to change anything from the past, but leaves it open for Dr. Evil to change things between replications. All you've got is timed snapshots, and you still have to trust how the system got from snapshot to snapshot.
David Thornley
A: 

You could add a trigger to send a copy of the data as it is entered to a non-production database that the evil admin does not have access too. The admin could stop the trigger from functioning, but the question was how to detect manipulation, not prevent it.

Aramis wyler
+2  A: 

I think this is a great question! But your scenario goes against the design principles of a database.

Row checksums, triggers exporting to other databases - anything you do will be a compromise!

I can only suggest something outside the box - would it help if you were to apply some type of standard such as PCI Compliance?

If that fails, I would suggest looking for another job! There is enough work in our industry where you don't need to work with these types of people...

Christian Payne
+4  A: 

Just run a paper log with your transaction ids, and keep the printer in a room with only 1 key. Work with financial systems, and you'll find that many of them still rely on their paper backups. Pretty much impossible to "hack" a paper log untraceably...It's why people keep pushing for paper logging in voting machines.

Lot of people are saying, "Just add another database" and although I actually practice this sort of logging myself, I don't trust it. A malicious insider could knock out that safeguard in a dozen ways.

All we're doing here is trying to find a way to make it obvious that something has happened. You're going to lose your logs. You're not going to be able to trust them: if I came across a system with a foolproof logging system, I'd either fill it with garbage data, or just wipe it entirely. Don't fall into a Maginot line mentality.

But if you prepare enough, so that too many failures have to happen, you can narrow the sabotage to an internal source. You need to log around the database, you need to keep extensive system logs, you need to monitor IP traffic, put a camera in the server room, leave a keylogger on the console, etc, etc. Even the best will slip up somewhere, and if you have enough mousetraps lying around, you might catch them somewhere by accident.

Satanicpuppy
+1  A: 

First, be very careful who you hire to administer your system.

Next audit tables populated by triggers. Even if he gets around the trigger for his changes, you can at least look at the data from before he changed it (especially from your backup).

Third automated backups that are removed offsite. This way even if the bad guy dropped the database and erased the onsite backup, you have a fallback position. Make sure the off-site backup is not accessible to the database admin, only someone else has the rights, someone who does not have production rights to the database server.

Next, no direct rights to the tables for anyone except the admin. This means using stored procs with no dynamic SQL. This at least prevents others from changing the data in an unauthorized fashion. Now it's harder for your accounting folks to commit fraud.

No production admin rights to anyone except the admin and one other as backup. This way if you find the trigger changed, you know who did it. Now anything goes wrong, you only have two suspects.

SQL Server 2008 has DDL triggers that tell you who made structural changes. Again, if the trigger didn't record the change, it was made by the admin by default.

Encrypt backups and certain personal data making it harder to steal. Now the off-site backup delivery person will havea harder time stealing your data.

Fire any admin who has proven to be untrustworthy even if it wasn't the data he was not trustworthy about. If he will fake a timesheet or steal office supplies, he will steal data. If he gets arrested for some serious crime (not a traffic violation), you can put him on suspension if need be to see if the accusasion is proven.

When the admin decides to move on to another job, do not let him have access to your system from the moment he tells you he is going. If you are firing him, this is especially important.

HLGEM
Bear in mind that, if you fire DBAs because you think they faked a timesheet, or suspend without pay if they get into legal trouble, and word gets out, you're making it harder to hire the replacement DBAs. Remember also that most people will be more or less trustworthy as you trust them more or less.
David Thornley
I said proven untrustworthy not I think he faked his timesheet but we proved it. And it's a standard practice to suspend people who have been arrested for something serious in any profession where trust is critical.
HLGEM
What do you do when you're pretty sure he faked the timesheet? You'll wind up with suspicion. Start an investigation and he's going to feel untrusted. BTW, most of the DBAs I've known didn't feel like they were in trust-critical professions, and wouldn't expect to be treated like it. You're proposing to raise the bar - not necessarily a bad thing overall, but it'll hurt your company.
David Thornley
I'm hesitant to treat people like they can't be trusted: there is no surer way to make someone untrustworthy. Likewise, while I DO automatically knock someone out of the database when they announce they're leaving, I do it because I want them to have to work WITH someone for the rest of their time, not because of trust issues.
Satanicpuppy
David, I have never met a dba who didn't know she or he was in a trust critical position. And any employee can expect to be investigated or fired if they commit fraud (which is what faking a time sheet is, I'm talking about charging hours that weren't worked).
HLGEM
Satanic puppy, I didn't say treat everyone like they can't be trusted, but there is no excuse for risking your business critical information when an employee has been shown to not be worthy of trust or when the person is in a position where he or she may no longer care about his or her actions. Many many companies recognize this risk and do not let anyone in IT touch their network or servers once they have given notice.
HLGEM
+1  A: 

I found this article, it looks interesting, could be a possible solution, although I haven't taken the time to try and think of exploits yet.


Off the top of my head I could picture having two separate databases, the "evil" sysadmin would only have access to one.

One database would provide one-time-pads to the other database and log who requested the pad and when. This pad, along with the current time and row data could be hashed.

This way if the evil sysadmin changed something the hash wouldn't check out, and if he tried to rehash you'd have a log of what time things should have happened.

If the sysadmin can store the time and one-time-pad then this whole system collapses.

This is a deceptively hard problem, I'm not sure that any protocol will really work, but adding physical security, and an audit log would be a good idea.

jessecurry
+1  A: 

If you want an automated approach, you would first have to know what actions and context were allowable for the user type. This is quite difficult, because in the right context a drop is acceptable, but its not for an everyday user.

I do like the paper backup idea, however the amount of information that is produces can become quiet large very quickly with a large user base and heavy DB usage.

monksy
+1  A: 

Consider creating a rolling, rapid, off-site, automated backup of your data. S3 is so cheap these days that one might cron a mysqldump-type process to transfer your entire repository of data to a Transatlantic backup store every so often. How often exactly will depend on the evilness of your DBA.

To make the process possible, simply find or institute a machine inside your network that the evil admin knows nothing about or wouldn't care to look at if she suspected anything. The simplicity and elegance of a plug computer can't be overstated here.

Note on the actual export mechanism: knowing nothing about your particular system, I suggested mysqldump or Oracle exp as the simplest and dumbest solution. If your application has a way of exporting data in a native format (such as XML, JSON, or even Protocol Buffers - in other words, any format that parts of a, say, SOA application use to talk to each other), then that format can be used as the format of your rolling dump.

I've implemented this approach on my gitosis box. Every three hours the contents get dumped to a European S3 bucket. It's a poor man's VCS of another VCS.

Max A.
+4  A: 

Lets be clear: if you assume an Evil Sysadmin, there is no cryptographic solution that will prevent them from being able to modify data on the system in an untraceable fashion - there are solutions that will prevent them being able to decrypt information, but nothing that can prevent them from writing new information in any way they see fit.

This situation requires the following conditions:

  1. That the system be, by necessity, stand-alone. If you can add another system in that the Evil Sysadmin has no access to as a logging host (say, a syslog server), then suddenly the problem becomes a trivial case of transferring logs or hashes on a regular basis.

  2. That the system not have non-software write-once components. The simplest ones, as suggested by others, are things like a printer, however you can use a CD or custom write-once hardware to prevent the issue. These get trickier but not insurmountable if the Evil Sysadmin has physical access to the machine.

  3. That you require certainty, rather than statistical likelihood. In the event that #1 and #2 are impossible, your only remaining solution is obscurification - the implementation of tricksy traps designed to catch the tampering if the Evil Sysadmin does not know about the trap.

The secret to an effective #3 is tactical surprise. The objective is to convey the impression, to the attacker, that they know all about any countermeasures, while in fact having more that they are not aware of. In general this requires at a minimum two levels of cover - you need to have at least one layer of protection the Evil Sysadmin can be expected to compromise because they will be looking for it, and if they don't find it they'll get suspicious and dig deeper until they do.

The important point is that this cover should be so convincing as to satisfy the Evil Sysadmin that, once they've found it, they need look no more. The second layer then identifies the tampering using alternative techniques and produces the appropriate alert. There are various suggestions in this thread re transactions etc that could be implemented. The lower the level of your solution, the more likely it is to succeed (ie, patch the database source code is far less visible than a standard process doing a connection and query, patching the kernel is less visible again, modifying the firmware..).

It is important to emphasize that this is not a perfect solution. However complex your setup, it is possible that someone has figured out/compromised sufficient information to implement countermeasures. That is not the case with #1 and #2 (done properly). That said, if the value of the information you're protecting is sufficiently low that people with the necessary skills will not be interested in working to obtain it, it should provide a workable defense.

Richard Clark
+1  A: 

Every few hours, make a hash of the table's contents. Also record the start and end row. For the second hash and on-wards, make a hash of both the contents of the entire table, and the rows hashed in the previous hash (the check hash). If the previous hash, and the check hash don't match, the database table has been tampered with. I would have these hashes emailed to you, so you can check if the rogue admin had gone through and regenerated all the hashes. I realise there is a gap, but I don't think there is much more then can be done (short of removing their access) than either this or what's already been mentioned.

Chris Clarke
+1  A: 

I like MikeMontana's solution but I thought it might be worth adding an addendum to it. Sadly I can't leave comments yet so I posted it in a new answer, the original is quoted below:

If you really must detect that tampering has occurred, then add a checksum field to the table. The checksum for each new row must include the checksum of the prior row. Then to verify the content, walk through the dataset computing the checksum as you move forward. If the calculated checksum doesnt match the value in the table then some value has been tampered.

-Mike

Several people pointed out: well the sysadmin could recalculate the checksum (even more an issue if you want to code to live on his server), to which I add the following enhancement:

when data is inserted into the table it is encrypted with a public key, thus anyone can add to the database (assuming you have multiple people using it). Periodically you decrypt the data using your private key and calculate the checksum. If it is different that means the database has been modified (what you wanted to test). You then recalculate the checksum and insert it into the table (public key encrypted as well, of course).

Should the evil sysadmin try to recalculate a new check sum he is doing it on encrypted data.

Additionally, if you are accessing this data remotely then this approach is immune to man in the middle attacks by having decryption and checksum calculations on a local box. Intercepted data will remain encrypted, and thus unusable.

The only flaw in this system is that any transaction to the database is detected. You can solve this by abstraction and say:

  • verify checksum
  • insert data
  • recalculate checksum

but this removes the advantage of having anyone you want access the data without giving out your private key.

Now it is possible to solve this problem in a different way, for which I would recommend you:

Addressing the trust asymmetry problem in grid computing

by Peter Dinda

http://portal.acm.org/citation.cfm?id=1066656

but the implementation details become longer.

tzenes
+1  A: 

While there are some very good suggestions here, they will all bite the dust.

Bacause you have an "untrusted" actor, the evil admin, as custodian of your data you cannot protect yourself. There are various schemes in network protocols and in the real world to enable you to protect your data from tampering by an untrusted transport/courier. But to the best of my knowledge there is nothing that can protect you from an untrusted custodian as in "Hi. I'm Mr. Madoff I used to be chairman of the New York stock exchange you can trust me .... ".

James Anderson
+1  A: 

Separation of Power/Dual Power controls.

I like the ideas that have been presented so far. I wanted to add my own 2 cents.

In the financial industry, separation of power has been key to keeping a single person from being completely evil. Our core processing solution is administered by our bookkeeping department (bless their hearts) so we programmers don't really get a whole lot of access to our live data.

Additionally a third party logs interactions with key parts of our system.

Overall, no one person has enough control to affect all the checks and balances, making the payoff diminish enough that its (hopefully) not worth coordinating.

fauxtrot
A: 

Since you evil admin has full control of the server, you probably need an external auditing solution that's designed to monitor the activity of privileged SQL Server users.

Guardium make a network appliance that can log all of the query activity on a database or a server, and it does it at the network level (including local connections) so you can't do anything at the SQL Server level to interfere with it.

This doesn't prevent your evil admin from changing the table but, because it's a locked down appliance, the evil admin can't change the table then persuade the appliance to say that he didn't do it.

KenJ