So, once you know what your program has to do, is that enough? No. A cursory reading of well-known security vulnerability lists (such as Bugtraq, CERT, or CVE) reveals that today, most security vulnerabilities are caused by a relatively small set of common implementation mistakes. There isn't a single standard terminology for these mistakes, but there are common phrases such as "failing to validate input," "buffer overflow," "race condition," and so on. Unfortunately, most developers have no idea what these common mistakes are, and they repeat the mistakes others have made before them.
Future installments of this column will delve into what these common mistakes are, and more importantly, how to avoid making them. In many cases, the way to avoid the mistake is both subtle and simple -- but if you don't know how to avoid the mistake, you'll probably repeat it.
In this column, I'm usually not going to try to separate different kinds of applications (such as "Web applications," "infrastructure components," "local applications," or "setuid applications"). The reason? Today's applications are increasingly interconnected, made out of many different parts. As a result, it's quite possible that your "single" application may have different parts, each of a different kind! Instead, I think it's better to learn how to develop secure applications in any situation, and then note when specific guidelines apply.
The next installment will start by covering how to validate input. This is trickier than it sounds. For example, we'll see why looking for incorrect input is a mistake, and how attackers can often sneak in illegal negative numbers without using the "-" character. Later topics will include avoiding buffer overflows, minimizing privileges, and avoiding race conditions. It will take a number of articles to cover the common mistakes, but by following this column, you'll be able to avoid the mistakes responsible for nearly all of today's software vulnerabilities.