views:

176

answers:

7

Such as deleting the output file during run, directing two instances of the sw to the same IO etc ?

+7  A: 

There isn't much you can do to prevent the user from doing that, but what you can do is to apply defensive programming.

In your two examples you'd have to, every time you access a resource, detect failure conditions and react appropriately either throwing exceptions and dying or continuing without access to that resource.

Never assume a resource allocation will succeed, always check what you don't control. In short, assume as little as possible and verify everything.

'I'm told to access this file to write to it. Is it already open? Do I have permissions? Does it have the expected format? Does the disk have enough space? etc.'

There is many more about this. Just Google for defensive programming and you'll get a lot to read about.

Vinko Vrsalovic
+1  A: 

Assume nothing. Check every operation that uses IO, every time. Put an extra layer in your software for IO with build-in checks.

+1  A: 

Put a maximum input length on each text box or edit control on the UI. Test with entering invalid data (e.g. text in edits where a number is expected) and put in place a common way of checking for/dealing with that kind of input.

Also think about SQL injection attacks via search terms. e.g. Look for people where the surname is ___, and the user enters "*smith"; select * from users*". What will the database layer do with that?

If the data that the users enters will be displayed back to them (or worse, to other users) see if they can embed any markup or control sequence into it that could abuse the UI when it is displayed.

You don't say what OS and language you are targeting, but look at giving the application the bare minimum privileges that it needs in order to execute. E.g. in .Net, look at the declarative security attributes. This means that if an attacker gains control of your app, there's less damage that they can do with it.

Create unit tests with intentionally bad input to verify that the application can cope with it.

Anthony
A: 

One thing I've heard of people doing is running untrusted stuff under VirtualPC, so that the base system can't get damaged no matter what.

T.E.D.
+1  A: 

There are some good answers here, but I think you need to consider what you would be defending against.

Is the program going to be used by people who want to use it? If so, you need to defend against stupidity (to the extent practical) rather than sabotage. You still want to check all inputs, but if a user does do something stupid, it's reasonable to get less-than-optimum results. If the user has access to the system, you may not be able to prevent things like deleting the output file, so you can't code for it. There are things that are just training issues.

Is the program going to be used by people who don't want it, such as a time-clock application to record when people punch in and out? Somebody needs to consider physical security (commercial versions are designed to take a lot of abuse), and software security (so nobody can alter the times). You need to provide a very simple interface and check inputs in detail.

David Thornley
"If the user has access to the system, you may not be able to prevent things like deleting the output file, so you can't code for it." <--- You certainly can and should make sure that your program fails gracefully instead of bringing down the machine with it, for example.
Vinko Vrsalovic
A: 

What about having good testers around that simulate user abuse?

Ced
A: 

This is a tricky question. Users (even dumb ones) can be clever about using your application in ways you've never considered.

I'm a big fan of defensive programming (as mentioned above by Vinko). You can approach it from a hazard analysis point of view. Look at the resources your application uses and modifies (files, devices, data, etc.) and brainstorm what could go wrong with those resources and plan around it.

If for example you have a dedicated hardware resource, and multiple instances of the application would each contend for that resource, you could force a singleton pattern for your application so that the user is unable to run more than one instance.

All this takes a bit of planning and work, but hey, that's what we get paid for :)

JettGeek