A recent article by Michael Howard in the November 2006 issue of MSDN Magazine discusses eight great habits when it comes to developing more secure code. Below are some excerpts and the link to the full article.
- Take Responsibility: Getting security right in your product is totally up to you. No one else – and certainly no magic tool or programming language – solves all security ills. Don’t get me wrong, I like source code analysis tools, but they will not magically fix all your security vulnerabilities. Only you can do that. Secure products are built by developers who create secure designs and write secure code. Ultimately, writing code is an individual endeavor. You are an individual, and you cannot be replaced by a tool. Therefore, the security of your product is your responsibility! (…)
- Never Trust Data: I’ve said this a billion times and I’ll say it again: all input is evil until proven otherwise. If you look at the most heinous security vulnerabilities, they all share the common trait that the developer trusted the incoming data. The problem is if your code assumes the data is well formed, what happens if your assumption is incorrect? On a good day, your application will probably crash. On a bad day the attacker could inject malicious code into your process and wreak havoc (…).
- Model Threats against Your Code: You do have threat models, right? Threat models allow you to understand the potential risks to your software and to make sure you have the appropriate mitigations in place. But the benefits of threat modeling extend beyond secure design. Threat models can help with your code quality, too. Threat models tell you where the data came from. Is the data remote or local? Is the data from anonymous users or is it from more trusted (authenticated) users, perhaps administrators (…)?
- Stay One Step Ahead: The security landscape evolves constantly. It seems that every week there are new variations of security issues. This means you must evolve and learn about new threats and defenses or you’ll suffer the consequences. (…)
- Fuzz!: Fuzzing is a testing technique that was invented to find reliability bugs. It turns out that a percentage of reliability bugs are security vulnerabilities waiting for the right exploit! Sure, a buffer overrun might crash an application, but given a well-crafted malicious payload, the crash might not happen, and the attacker could run code to do his bidding instead. Our motto around here is “today’s denial of service is tomorrow’s code execution.” (…) If you get a crash, don’t think it is only a crash. It is likely that a good percentage of these so-called crashes are begging for someone to write an exploit. So don’t simply punt a crash as “just a crash.”
- Don’t Write Insecure Code: At Microsoft, we use the concept of quality gates to help reduce the chance a developer will check vulnerable code into the product. The gates run a battery of source code analysis tools on the code prior to check-in to flag any issues. And any identified issues must be fixed before the check-in can be completed. (…) Don’t reinvent functionality. If you have code that parses a specific file format, you don’t need two or three sets of parsing code; stick with the one set, make it robust, and wrap it up in a form that can be used across multiple projects.
- Recognize the Strategic Asymmetry: Remember that as a software developer, the security odds are stacked against you. I like to call this the “Attacker’s Advantage, and the Defender’s Dilemma.” You need to get the code and the designs 100 percent correct 100 percent of the time, and that is impossible. To make matters worse, you must reach this insurmountable goal on a fixed budget, on time, while having to consider requirements of supportability, compatibility, accessibility and other “-ilities.” An attacker can spend as long as he wants to find one bug, and then announce to the world that your application is insecure. (…)
- Use the Best Tools You Can: Use the best tools you possibly can. I love source code analysis tools and I love any technology that helps me write more secure code. As I mentioned, tools are no panacea but they help. A lot! Tools also help scale the problem of source code analysis. Tools can scan huge quantities of code rapidly, much faster than a human could. And this helps give you a feeling for how “bad” some code might be. (…)