Defensive programming: Difference between revisions

Content deleted Content added
link to articles on "defensive programming"
mNo edit summary
Line 2:
 
Here are some hints on defensive programming techniques to avoid creating security problems.
Many of these techniques also improve general quality of code, because almost any major [[Software bug|bug]] can be potentially used by a [[cracker (computing)|cracker]] for a [[denial-of-service attack]] or other attack.
<!-- So is defensive programming *only* used to avoid creating security problems? Or is it also used to avoid bugs when trusted users make silly mistakes? -->
 
Line 8:
 
<!-- Please expand this article. These random notes should be changed to a more coherent article. -->
 
* One of the most common problems is unchecked use of constant-size structures and functions for dynamic-size data (the [[buffer overflow]] problem). This is especially common for [[string]] data in [[C programming language|C]]. C library functions like <tt>gets</tt> should never be used since the maximum size of the input buffer is not passed as an argument. C library functions like <tt>scanf</tt> can be used safely, but require the programmer to take care with the selection of safe format strings, by sanitising it before using it.
* Never make code more complex than necessary. Complexity breeds bugs, including security problems.
Line 22 ⟶ 21:
name of this file, like "/etc/../etc/passwd".
 
Preconditions[[Precondition]]s, postconditions[[postcondition]]s and invariants[[invariant]]s validation are also part of defensive programming. This may involve checking arguments to a function or method for validity before execution of the body of the function. After the body of a function, doing a check of object state (in [[OO]] languages) or other held data and the return value before exits (break/return/throw/error code) is also wise.
 
Within functions, you may want to double check that you are not referencing something that is not valid (i.e., null) and that array lengths are valid before referencing elements with indexes on all temporary/local instantiations. A good heuristic is to not trust the libraries you did not write either. So any time you call them, check what you get back from them. It often helps to create a small library of "asserting" and "checking" functions to do this along with a logger so you can trace your path and reduce the need for extensive [[debugging]] cycles in the first place. With the advent of logging libraries and [[aspect oriented programming]], many of the tedious aspects (yes, a pun) of defensive programming are mitigated.
Line 28 ⟶ 27:
Generally speaking then, it is preferable to throw intelligible exception messages that enforce part of your [[application programming interface|API]] contract and guide the client [[programmer]] instead of returning values that a client programmer is likely to be unprepared for and hence minimize their complaints and increase robustness and security of your software.
 
== References ==
-------------------------------------
 
Books:
* William R. Cheswick and Steven M. Bellovin, ''Firewalls and Internet Security: Repelling the Wily Hacker'' ISBN 0201633574 http://www.wilyhacker.com/
 
== External references:links ==
* [http://www.dwheeler.com/secure-programs "Secure Programming for Linux and Unix HOWTO"] by [[David A. Wheeler]]
* [http://embedded.com/showArticle.jhtml?articleID=9900044 "Proactive Debugging"] article by Jack Ganssle 2001-02-26 <!-- would this be more appropriate in the [[debugging]] article? -->