Somehow I missed the first edition of this book, and when I look at the contents I get a feeling that quite a few people in Microsoft also missed it. Before you read any further you should know that this book is very much specific to those writing for Microsoft OSs. No doubt those writing for Linux, System X etc. could gain some useful insights into the general principles of writing secure code, but much of the text is aimed at addressing the problem on MS based systems that would considerably reduce its value to such readers. The problems would be largely the same but the solutions could be very different.
The book is divided into four parts followed a set of short appendices. In part 1 the authors introduce the current position and highlight why it is different from the past. For example, right at the start of chapter 1 we have:
As the Internet grows in importance, applications are becoming highly interconnected. In the "good old days," computers were usually islands of functionality, with little, if any, interconnectivity. In those days, it didn't matter if your application was insecure - The worst you could do was attack yourself - and so long as an application performed its task successfully, most people didn't care about security.
This sets the motivation for the whole book and in a sense provides a justification for the very poor security that many Microsoft products suffer from. In the days when viruses where transmitted by floppy disks, good discipline by the computer owner was largely sufficient. The developing theme in this section is that times have changed and developers need to change with them. The concluding chapter of this section highlights the degree of change necessary by tackling the issue of threat modelling.
In part 2 the authors cover the more straightforward aspects of secure coding. Inevitably they start with the problem of buffer overruns. Here it is interesting to note that they repeatedly emphasise that such tools as the .NET /GS (similar to Crispin Cowan's StackGuard for GCC produced apps.) option are not a replacement for responsible programming. The need for responsibility and understanding is a continuing thread in this book. In affect the authors are saying that producing and distributing an application without understanding potential abuse and protecting against such is unacceptable. I agree with them, but it will take many years to remove all the dangerous legacy code and applications that are in regular use round the world. Just imagine the reaction if Microsoft stated that it was withdrawing the licence to use all versions of Windows prior to some new release (let us call it SXP) on the grounds that they could be exploited to damage other users (which, of course, they can via such things as denial of service attacks). That raises an issue that is not covered in this book, the need for responsibility and understanding amongst computer users (for example, all users of always-on Internet connections have a responsibility to ensure that their systems are kept secure).
The chapter I particularly enjoyed in part 2 is the one titled All Input is Evil . This is something that needs to be drummed into programmers from day one. This chapter starts with:
If someone you didn't know came to your door and offered you something to eat, would you eat it? No, of course you wouldn't. So why do so many applications accept data from strangers without first evaluating it? It's safe to say most security exploits involve the target application incorrectly checking incoming data or in some cases not at all.
The rot starts with books written for newcomers to programming. Pick up any one of them aimed at introducing C or C++ and look at the sample code. I will lay very heavy odds that input is via scanf() or gets()in C, and operator in C++. The student is taught to trust input by default. This must be wrong.
In part 3 the authors deal with several higher-level security issues such as socket security. While the book is generally very much targeted at developers for Microsoft OSs, this section is very strongly oriented this way.
The final part of the book is titled Special Topics and is concerned with such things as testing, code reviews and documentation from a specifically security viewpoint. This part includes an excellent chapter on General Good Practices . Those of you who feel complacent about the security of your equipment might note:
Because of these design features, any service that opens a window on the interactive desktop is exposing itself to applications executed by the logged-on user. If the service attempts to use window messages to control its functionality, the logged-on user can disrupt functionality by using malicious messages.
I guess many of you are going to feel irritated by my conclusion to this review but if you write software to run on a PC using a Microsoft Windows OS you should read this book and be familiar with what the authors have to say. And if you feel complacent because you use some other operating system such as Linux, it is time to wake up and recognise that the world has moved on and security is everyone's responsibility. Defensive programming these days isn't just a matter of asking what can go wrong, but requires that you ask yourself how your work can be abused. Of course, if you are just writing a small application for your own personal use which does not rely on any widely available library then you can probably still adopt the attitude that only you will pay for your mistakes.
This is not a book that I recommend because it will improve your ability to write good code, it is a book that I consider to be essential reading by any responsible developer (the only people I will exempt are those that are already working in teams that routinely require such things as threat analysis on their work) so that their code does not damage others. ACCU does not have a recommendationclassification for books like this one. Perhaps this should be the first book under a new heading: Essential Reading for Developers for MS Windows .