Writing Secure Code

So, after reading “Writing Secure Code, Second Edition”, I've totally changed the way I program. Here is a prime example, taken from the book:

Many vulnerabilities come from data entering into the system which deviates from the expected parameters. For example, a typical piece of code might look like this:

DWORD dwRet = IsAccessAllowed(...);
if (dwRet == ERROR_ACCESS_DENIED) {
    //Security check failed
    //Inform user that access is denied
} else {
    //Security check OK.
    //Do something
}

Sure, this code looks fine. But what happens when something unexpected happens, like the system runs out of memory? Well, if the system returns ERROR_NOT_ENOUGH_MEMORY, you're screwed cause now the user has unrestricted access.

Most people assume benevolence when writing code. That, if you write something good enough, you will always be able to anticipate what the result will be. This is simply not the case. It's really easy to change your thinking though... just reverse the flow, and fail securely.

DWORD dwRet = IsAccessAllowed(...);
if (dwRet == NO_ERROR) {
    //Security check OK.
    //Do something
} else {
    //Security check failed
    //Inform user that access is denied
}

So now, I'm rewriting some of this code for the XHEO|Licensing web services implementation. I wanted it to use a DAL and SPROCs because they're more secure, and I don't have to open up direct-query permissions on my DB (which as many of you know is my A-number-1 pet peeve. I've built-in a lot of data checks into the system, turning voids into functions that return a Success/Failure boolean. I have yet to determine if it is possible for a boolean to return Nothing/Null, or if it just shows up “False”. If it can't, then I may have to create a custom tri-state data type (unless you guys know of another solution. I also thought about turning all of my booleans into System.Object, and doing a CType(Boolean) if I get something, or returning Object = Nothing if I get an error. I think that would be much better than throwing an exception (exceptions are very expensive on the system), but I'm still experimenting.

I've talked about a lot of stuff here. I'd really like some feedback regarding this stuff. What do you guys think? Is it possible to return Nothing in a boolean and have it not equal false? Should I be doing so many data checks? What about this secure failover stuff? Do you guys use it? Please take a few minutes and let me and the community know what you think.

UPDATE: Paul from Xheo frickin rocks, as usual. His yet unreleased copy of the Xheo Base Library includes a new Value type called TriBoolValue, which is almost the same as Microsoft.VisualBasic.TriState except it does automatic boolean conversions. SLICK STUFF MAN. Does exactly what I needed it to. Oh yeah, and the XBL is free. :)

5 Comments

  • I would use exceptions, because if I understand it correctly, that is exactly what this is... an exception. Exceptions may be more expensive than some of the alternatives, but if is truly an exception, meaning that it will not happen very often, then it should not be a performance issue.



    I think alot of times we get stuck programming for the exceptions, when instead we should be programming for the norm and accomodating the exceptions.



    -James

  • I agree exceptions are the way to go. As for validating parameters/properties, etc. I am a firm believer in the use of Validator classes. For example:



    public string SomeMethod(

    [StringNotNullValidator()]

    string param1 )

    {

    (new MethodValidator).Validate(

    this, "SomeMethod", param1);

    }

    This implementation is something I have written, but the premise of what you are talking about is the same ( I think ). Defensive coding will always save you many headaches down the road.



    -Mathew Nolton



  • Good post. Something than Kernighan & Pike address in "The Practice of Programming".

  • Don't remember how long ago it was or where it came from but I've always tried to adhere to the notion of "positive tests" which tends to avoid the notion of "assuming benevolence". So personally I would've written:



    DWORD dwRet = IsAccessAllowed(...);

    // if success

    if (dwRet == 0) {

    else

    //Security check failed [for whatever reason]

  • John,



    I may be mistaken, but isn't that what my second example in the original post showed?



    -Robert

Comments have been disabled for this content.