Wednesday, December 12, 2007

Naive Computer Security

I love Jeff Atwood's blog, Coding Horror. This guy posts something new and interesting for CS nerds to think about almost every day, and has really inspired me to get into blogging with his gratuitous self-referential blog posts about blogging. So I thought, instead of posting a comment on today's ridiculous article, "why not blog about it"?

It seems to me that malware prevention takes three forms. Don't let it execute, don't let it do what it wants to do, and of course, get rid of it once it's started doing that stuff.

Don't let it execute

Executables
It means nothing to have a virus sitting on your hard drive if it isn't ever triggered to execute, right? This is where user intelligence comes in: just don't run stupid programs! With enough internet experience, people learn how to spot these: they usually say FREE in big flashy letters but have no GPL to be seen, and often advertise unlicensed third party addons for commercial software-- mostly web browsers and chat clients. If it says "50 free smilies plus fun sounds and flashy goodness!" please don't run it. Video codecs and plugins you've never heard of that show up on advertisement-ridden porn sites are another danger.

This is the sort of thing a good antivirus program can be helpful with: warning the user before they run something stupid. And good antivirus programs do this. Unfortunately, they tend to get things wrong more often than not, because as Atwood says, they are indeed working with blacklists. For example, my favorite free antivirus program AVG still makes false virus detections on any game made in the excellent game maker program Multimedia Fusion because they happen to use a compression algorithm that has historically been used in viruses. Clearly blacklists are no great idea, but at least they do something. The rest is up to your own intelligence and experience.

Non-Executables
Unfortunately, it's not quite that simple, because many viruses come in the form of data specifically designed to break the program interpreting it and execute arbitrary code through it. This is where the Outlook JPEG exploits come in. If this happens, it is usually not the fault of the user at all. In fact, it is everyone else's fault.

1) It's Intel and AMD's fault for not making the program text segment read-only
2) It's The C Programming Language's fault for making it so easy to cause buffer overrun
3) It's the software developer's fault for using C/C++ without rigorously testing all forms of buffer overrun and misinterpretation of data
4) It's the operating system's fault for letting the compromised program do as it pleases

While the first one may never be fixed, the second is rapidly improving as new languages gain popularity. Even something so simple as writing your programs to compile to a virtual machine like M$.NET or JVM acts to combat this problem quite well. Stages three and four here are the way things are traditionally done, albeit ineffectively. It just makes me wonder how much better a place the world would be if we could fix #1.

Then again, if there's a fix to the software or OS that the user hasn't applied yet, it is indeed their fault.

Don't let it do what it wants

This is where permissions come in. And Atwood is correct: avoiding running as an administrator is a great form of protection. If an exploit can't modify core application files, it will have a hard time living after you restart the application, and an even harder time of causing damage to the main system. It can, however, insert itself into user-space startup scripts to keep itself going, and do whatever it wants to the current user's files. In fact, on most systems all files anywhere are readable, and won't really hide their data from a user-space virus. The virus simply has to transmit them over the internet. And that's where things like Windows Firewall come in, in the class of defense by not allowing processes to do what they want.

Of course, with all the permission / behavior checks in the world, there is still the problem of users who will just click OK GO AHEAD by reflex, and end up enlisting their poor machine as a slave in someone's epic DDOS army of doom. Though even without the clueless user response, permission systems can be circumvented via buffer overrun and exploits in just the same way that data can take over an application, so long as the target application has some of the desired permissions. So until we invent unbreakable applications (or Intel and AMD do, you know, that thing), we're back to: don't run dodgy stuff on your computer!

Get rid of it once it's there!

This is the feature antivirus programs advertise. They inspire fear and doubt and paranoia in their poor users to the point that everyone seems to immediately think they have a virus as soon as their computer starts acting weird. The methods they use, however, are often kludgy and awful, and will make you wish the virus was never there to begin with. Experienced sys-admins who find their machine has been compromised would often rather re-install the operating system than deal with disarming the threat, for fear of hidden backdoors. However, they do offer a quick fix for common users that isn't too bad, so why not run a virus checker every so often. At least it sort of gives you peace of mind.

Personally, I'm a naive computer user, and will more often than not run a game I maybe shouldn't. But it's comforting to have all three levels in place there, to catch the majority of problems before they get too big. After all, nobody has designed the ultimate exploit that is immune to every form of protection and survived it for more than a month.