Secure Coding: Principles & Practices

August 28th, 2007

31a4xgqm9dl_aa_sl160_.jpgI read Graff and van Wyk’s Secure Coding: Principles & Practices to completion, but not because each page was more enlightening than the previous. I realized that the same themes and adages were being repeated constantly after having read half the book. Because it was pretty easy to get midway through the book, I decided on continuing through it for the sake of completeness. As critical as I can be about the book, there are characteristics of the book that may be redeeming.

The lessons that the authors attempt to convey seem to be an extension of what is taught in a typical software engineering course. Being about security, the book suggests that software engineers keep security concerns in mind while proceeding through a development life cycle. While testing and designing, the book suggests without going into specifics, software engineers should think about ways that other entities may try to subvert their application systems. The authors encourage implementing systems with a high degree of visibility, accountability, and traceability. They also stress the need to consider the security of an application’s target environment. Normal review of the a and testing of an implementation during a software development life cycle should already address security concerns. The book serves to make this point explicit.

The authors’ principal ideas are repeated throughout the book. Perhaps, the authors believe that people retain about 10% on average of the information that comes to them, and the authors feel they need to repeat their lesson at least ten times to guarantee its reception. The book should not be discounted as a waste of time. After all, the stories, other than the same SYN flood and buffer overrun examples that are used throughout the book, were fairly entertaining.

On the Lack of Exceptions

August 9th, 2007

Lately, I’ve been helping develop a reasonably sized application, which detects errors at every operation. Checking the return value of every function call seems awkward when compared to code that is written in rather informal working environments. Writing code that checks each return value is frustrating when a feature that exists in another language is not available in the current implementation language. A function signature that may allow for the detection of a function’s failure is as follows:

STATUS operation( ArgType1 arg1, ArgTypeN argN );

The only qualm I have with the above function signature is that operation() is inconsistent with the mathematical notion of a function. Instead of having y = f(x), where the parameters to f() are unchanged, the function signature above has a return value set of {SUCCESS,!SUCCESS}, and the result of the operation may be stored at a memory location that is passed as an “out” parameter. Although operation() is less function-like, I like this method more than the use of global variables and additional function calls for error checking.

An apparent problem, or nuisance, occurs when multiple calls to operation() are made and error checking with handling needs to be performed. The code becomes saturated with conditionals and possible duplication of error handling code:


if( SUCCESS != operation(arg1,arg2) )
{
	/* error_handling_code_1 */
}

/* omitted_code_1 */

if( SUCCESS != operation(arg3,arg4) )
{
	/* error_handling_code_1 */
}

/* ommitted_code_2 */

if( SUCCESS != operation(arg4,arg5) )
{
	/* error_handling_code_1 */
}

This situation is just screaming for the use of exceptions. Exceptions would allow the code to be easier to read, and the implementation of the error handling code can be more disjoint from the function call that is experiencing the error.


try
{
	operation(arg1,arg2);
	/* ommitted_code_1 */
	operation(arg3,arg4);
	/* ommitted_code_2 */
	operation(arg4,arg5);
}
catch( ExceptionType1 arg )
{
	/* error_handling_code_1 */
}
catch( ... )
{
	/* if a given exception is not handled here, */
	/* it may be possible to rethrow the exception */
}

Although the target system might not have exception support, having to implement the discussed code helped me appreciate exceptions.

Transitions

July 14th, 2007

Transitions are always difficult.

While in Deutschland

June 18th, 2007

bundesflagge.gifI have been at Germany for two weeks out of the last month. I took on a task that I thought was theoretically possible, but one where completion under given time and resource allocation constraints was uncertain. The situation called for code developed in a proprietary environment for many months by many people to be ported to another proprietary environment. I took advantage of several software engineering methods, many that I have read about and adopted, to bring about success.

Success in this task was based on several factors that were set in the past. Many of these factors were not and could not be influenced by me. For example, the decision to adopt a highly portable programming language was crucial in the success and ease of the porting effort. Development of the code base started long before I joined the team, and I am glad that the team was steered toward the currently used programming language. Porting an application that is implemented in Visual Basic to a Unix-like environment seems more daunting or even impossible than porting a program that is implemented in C from a Microsoft Windows environment to a Linux environment.

The power of abstraction, interfaces, and separation of concerns were evident in the somewhat rushed porting effort. A well-defined interface of the source environment eased the implementation of the interface within the destination environment. Porting the code was a task of implementing the code’s functional dependencies. After the porting effort was completed, any and all code that is implemented for the source environment could be introduced to the target environment with little to no changes.

I tapped the help of several specialists of different facets of the code base. Specialists of the tools were also helpful. Without their help, the porting effort would have failed. Two weeks is simply not enough time to learn all the details of the code base and source environment, and implement the needed constructs on the target environment. People provided assistance in the form of functional implementation, problem diagnosis, and code examples. We brought about success together. This effort has provided me with a lot of experience, and I hope to find time to write up a couple of postmortems and share the methods that I used to help bring about success.

Configuring the Mouse Scroll Wheel

May 10th, 2007

Having packed my stuff just in case the Griffith Park Fire of ’07 drew closer to home, an opportunitity was created to rearrange my workspace. Rearranging my computers has allowed me to connect a keyboard and mouse directly to one of my principle development machines. I have been interfacing with the machine through VNC up until now, and I just noticed that the scroll wheel was not responsive when I was browsing the Internet with Mozilla Firefox. I spent a couple of hours trying to get it working, so here is my /etc/X11/xorg.conf file that allows my Logitech MX300 Wheel Mouse on CentOS 5 running X11R6 to function:


# Xorg configuration created by pyxf86config

Section "ServerLayout"
        Identifier     "Default Layout"
        Screen      0  "Screen0" 0 0
        InputDevice    "Keyboard0" "CoreKeyboard"
        InputDevice    "Mouse0" "CorePointer"
EndSection

Section "InputDevice"
        Identifier  "Mouse0"
        Driver      "mouse"
        Option      "Device" "/dev/input/mice"
        Option      "Protocol" "IMPS/2"
EndSection

Section "InputDevice"
        Identifier  "Keyboard0"
        Driver      "kbd"
        Option      "XkbModel" "pc105"
        Option      "XkbLayout" "us"
EndSection

Section "Device"
        Identifier  "Videocard0"
        Driver      "nv"
EndSection

Section "Screen"
        Identifier "Screen0"
        Device     "Videocard0"
        DefaultDepth     24
        SubSection "Display"
                Viewport   0 0
                Depth     24
        EndSubSection
EndSection