Programmers often like to talk about how a new tool or a new version of their favorite platform will make coding faster, easier, or more elegant. Although this may be true, it ignores just how difficult and painstaking the process of developing quality software actually is, no matter what tools are used.
Case in point: the CWE/SANS list of the top 25 most dangerous software errors. Each year, the list's editors draw upon the experience of leading software security experts to rank programming errors by frequency, severity, and the likelihood that they will lead to exploitable vulnerabilities. This year's list was published this week, and the bad news is how few surprises it contains.
[ Get software development news and insights from InfoWorld's Developer World newsletter. | And sharpen your Java skills with the JavaWorld Enterprise Java newsletter. ]
Not only is this year's list predictable, it's redundant. Of the 25 errors cited, far too many can be chalked up to the same fundamental misdeeds -- mistakes that have been around almost since the dawn of programming itself. Will we never learn?
The same errors, over and over
SQL injection is usually the result of improperly validated user input, where the application parses form data into a SQL query without checking to see whether it contains potentially harmful SQL code. But SQL injection isn't the only way user input can go wrong. Of the top 25 errors list, roughly a quarter of them can be attributed to inadequate input validation, including OS command injection, buffer overruns, cross-site scripting, failure to validate directory paths, and uncontrolled output formatting strings.
Even more than input validation errors, this year's top 25 list is rife with application security blunders of all kinds. Some of them sound fairly esoteric, such as "inclusion of functionality from untrusted control sphere." But of all such errors, the highest-ranking one on the list is "missing authentication for critical function" -- in other words, the attacker was able to gain access because there was no lock on the door to begin with.
Developers make such errors for two main reasons. First, they may be operating under the mistaken assumption that a given function is too obscure to be vulnerable; they fail to grasp the extent to which attackers may be willing to analyze their application flows to find weaknesses. More often, however, they simply haven't considered how important a given function might be to the overall security of their application. As applications grow more complicated and their functions are distributed across multiple systems and resources, it's particularly easy to lose track of the big security picture.
What we can learn from our mistakes
First, know your tools, and don't accept their features blindly. Among the specific recommendations given in the CWE/SANS list are such gems as "If you are using PHP, configure your application so that it does not use register_globals." This particular advice is as old as the hills, and it has actually been the default configuration since PHP 4.2. As of PHP 5.3, the feature in question has been deprecated. Developers who persist in using risky platform features because they're there, despite countless recommendations to the contrary, deserve what they get.
Second, don't put too much faith in your platform just because it's said to be more secure. For example, managed languages such as Java and C# eliminate the possibility of buffer overruns by doing bounds-checking at runtime. That means Java and C# programmers are shielded from the third-ranked error on the CWE/SANS list. But neither Java nor C# does anything to protect you from SQL-injection vulnerabilities caused by poorly validated user input, which rank even higher on the list than buffer overruns. Any platform is only as secure as the code that runs on it.
Third, data security is hard. Unless you're a specialist, cryptography seems like an arcane art, and it's tempting just to treat it simply as magic dust that you can sprinkle onto your applications to make them more secure. Similarly, it's all too easy to introduce backdoors in your authentication scheme if you don't treat security as a core principle in your software design process. Improper, inconsistent, or naïve application of security techniques is especially insidious because it fosters a false sense of safety even as it leads to serious vulnerabilities.
Last, and most important, the list reminds us that software vulnerabilities are everywhere, and virtually no development project is completely safe. With the pace of Internet attacks accelerating, now is not the time to cut QA staff or skimp on testing and code review. No matter what tools you choose, developing secure applications is challenging and laborious, yet critically important, now more than ever. Let's be careful out there.
This article, "Developer error: The most dangerous programming mistakes," originally appeared at InfoWorld.com. Read more of Neil McAllister's Fatal Exception blog and follow the latest news in programming at InfoWorld.com. For the latest business technology news, follow InfoWorld.com on Twitter.