Least Privilege - Still Unusable

March 31st, 2006

Quite some time ago, I argued that unprivileged users were too annoying to be usable in Windows. Today I took shipment of a shiny new computer and figured that for once I might actually try applying all these ideas that are meant to make Windows secure. Previously I've just kept Windows safely behind a firewall and done my web browsing and email on my Mac - essentially eliminating any way for unvetted code to get to my PC.

So I set off and created a limited user account, logged in as admin to do the initial setup of installing programs and what-not, then switched to the limited user. Some of the programs I'd installed had annoyingly placed shortcuts on the desktop so I tried to delete them. Turns out they're in the Shared user directory and my limited user doesn't have permission to delete them. Yep, that's right, by default most installers will add icons to my desktop that I have to switch users to delete. Great….

Then I opened the start menu. This time it was Microsoft adding useless crap to the start menu and again, it belongs to the shared user so I couldn't delete it. Sigh. This is getting annoying very quickly.

So I thought I'd just play a game and forget about it all. Call of Duty 2 came with my graphics card so I tried it out. "Please log in as an administrator and try again." Wonderful! Aha! I think, I can just use this little run as trick and get around that. "Please log in as an administrator and try again." So much for that.

So that's a total of three things I wanted to do, three things I couldn't and the prospect of having to change users just to play a game. Forget this - I'm running as an administrator user again.

So if someone on the windows "make limited user accounts usable" team happens to find this (prodding Scoble), might I suggest eliminating that damn shared users folder - I want to control wants on my desktop and start menu, get out of my way - and coming up with a better system for running an app as another user. The current attempt is crap.  In the mean time, I'll browsing and emailing from my Mac.

Testing Interface Contracts

March 27th, 2006

Often when you define an interface there is a series of generic tests which can be applied to every implementation of that interface. For instance, the java.util.List interface carefully defines the behavior that all implementations must have. A simple way of testing these behaviors are present is to use JUnit's ability to inherit test methods.

Define a base class with a test method for what you want and an abstract method to create the actual instance:

public abstract class ListTestBase extends TestCase {
    public void testAdd() {
        List impl = createList();
        Object expected = new Object();
        impl.add(obj);
        assertSame(expected, impl.get(0));
    }

    protected abstract List createList();
}

Then simply extend ListTestBase when you write the tests for your list implementations and they will all inherit the testAdd method. This can be useful anytime you want to apply a common set of tests to multiple different classes.

Making Trojans Easier To Remove

March 26th, 2006

It occurs to me that there's no way to stop trojans from working - there will always be a way to disguise it so that it looks like a valid application - if by no other means than by making it a valid application. There is also no way to allow the user to get their work done and prevent trojans from doing any damage or being annoying - even with privilege separation, the trojan has access to all the user's files. Note that this only applies to trojans, not to other types of malware - viruses for instance can be prevented by writing secure code.

It seems to me that we should instead focus on making it easier to remove trojans. This happens to be the greatest failing of Windows and it's mostly caused by the fact that you can't remove a file that is in use. So as soon as the trojan loads, nothing can delete it's files and the trojan loads on boot so you're pretty much screwed. There are even some trojans - like the one I've been dealing with recently - that embed themselves in the OS so that they run even in safe mode. As best I can tell the only way to remove it is to reformat.

If however Windows allowed me to delete the infected file or replace it with an uninfected version while the trojan was running, I'd have a much better chance of fixing the problem. The problem of course would be that the trojan could just replace the file again, leading to the second thing that needs to be fixed.

There must be a simple way for every single process on the system to be listed, interrogated and killed. No ifs, no buts and absolutely no way of hiding them. Anything that's not in the list doesn't get assigned any resources ever. Even better though, why not allow the user to click on a window and mark the process as malware? Never allow that executable to load again. That way when you get ads popping up on your desktop, you mark the process as malware and the trojan is immediately disabled - even though the files are still lying around on the drive. This isn't as simple as it sounds though - if a trojan loads IE and points it at a web page to display an ad, marking that window as a trojan needs to disable the executable that triggered IE to launch and not IE itself. Any number of other applications might be used as a proxy to get windows on screen and the OS has to work out who to blame for it. Applying the same concept to task bar items and so on would be extremely powerful if it could be made to work.

Just please, whatever you do, don't add yet another dialog checking that the user wants to run the file - they have no idea that it's a trojan so you'll achieve nothing. You only discover it's a trojan after you run it.

Refactoring Without Tests

March 22nd, 2006

Refactoring without tests is hard and really, really scary but sometimes you've inherited (or perhaps written yourself) a big ball of untestable mud and the only way out is to refactor and make it testable. One of our engineers found himself in that situation today so we sat down together to try and make sense of it.

I tried to follow a few simple rules:

  1. Go slow. No big sweeping changes. Keep the way it does things the same and just break the code down to make it more readable and create multiple small balls of mud instead of one big one.
  2. Use the automated refactorings in the IDE unless you absolutely have to make manual changes. We discovered a number of bugs in Eclipse this way where it didn't detect identical code - who knows why not. In once case I managed to convince it the code was identical by repeatedly trying the extract method until it picked up the duplicate block but in a second case I had to revert to manually replacing the duplicate code.
  3. Use the simplest refactoring that could possibly make it testable. Mostly this meant applying extract method with a smattering of extract local variable to pull out the differing pieces so duplicate code could be merged. In hind-sight I may have been better off leaving the duplicate code in and writing tests for it separately, it would then have been easier and safer to remove the duplication.

All in all I think it went really well, slow going but effective and we now have half as much code and it's much easier to test. There's still a lot more work needed to stop that code from smelling but it's a start and that's enough for one day. You can't spend all your time refactoring legacy code, new features have to be added - just make sure that you're constantly improving and eventually you'll get there.

Stats Should Rotate, Not Reset

March 22nd, 2006

I've come to discover a really annoying trend among blog statistic services - they all seem to show graphs of vistors by day, week or month instead of showing the past 24 hours, 7 days or 30 days. The difference is quite substantial, by viewing by the past 24 hours you always get a useful graph, by viewing by the day at the start of the day there's just a blank graph.

Is it really that hard to offer a previous 24 hours option as well as a by day option?