Slashdot Mirror


How to Develop Securely

An anonymous reader writes "This column explains how to write secure applications; it focuses on the Linux operating system, but many of the principles apply to any system. In today's networked world, software developers must know how to write secure programs, yet this information isn't widely known or taught. This first installment of the Secure programmer column introduces the basic ideas of how to write secure applications and discusses how to identify the security requirements for your specific application. Future installments will focus on different common vulnerabilities and how to prevent them."

5 of 47 comments (clear)

  1. Article Summary: by Farley+Mullet · · Score: 4, Informative
    There are basically two parts to the article:
    1. An unfortunately much needed reminder to use common sense, and;
    2. A way too long discussion of what exactly "Free" and "free" and open source software is.
  2. How to develop securely in 4 words by squiggleslash · · Score: 5, Informative
    Use strncpy() not strcpy().

    (Well, ok, perhaps it's more complicated than that, but that's a good start)

    --
    You are not alone. This is not normal. None of this is normal.
    1. Re:How to develop securely in 4 words by Circuit+Breaker · · Score: 4, Informative

      Ahhhm.

      Use strlcpy(). strncpy is almost as bad as strcpy(), as it doesn't guarantee a terminating nul.

    2. Re:How to develop securely in 4 words by Curien · · Score: 4, Insightful

      How about (radical idea coming) we just all use the functions correctly! strcpy is not inherently insecure, it just doesn't check anything /for/ you. strncpy doesn't guarantee a terminating null character, so you have to (gasp!) check for it.

      The main problem with strlcpy is that it's not standard, hence it may not be available on your target platform.

      --
      It's always a long day... 86400 doesn't fit into a short.
    3. Re:How to develop securely in 4 words by klaxor · · Score: 5, Informative
      After that, maybe we can look into programming languages that actually have a string type, and don't tend to make every bug exploitable by default.

      Yeah, whatever. Why not teach people to write correct code instead. And BTW, what happens when your String class runs out of memory? (Yes, I've seen code which reads an entire file into a String....) So I guess it's better to segfault than risk buffer overrun?

      After programming in C++ for a number of years, I've stopped using the string types, and actually gone back to using regular C-style strings. Here's why:

      • The String types dynamically allocate memory. Hence, an operation such as this:

        string1 = string2 + string3;

        can fail. This doesn't leave you with any options; either you wrap every string assignment in try/catch blocks, or you just hope it works. Compare this with the following in C:

        char string1[80];
        char string2[40];
        char string3[40];

        ...

        strcat(string1,string2);
        strcat(string1,string3);

        The above code can't possibly fail. There's no need for try/catch, or needless error checking - the destination array will always be large enough.
      • With the datasets I've been using, I quite frequently run out of memory. Since a string allocates memory on the fly, any memory allocation failure will happen in the middle of the algorithm, rather than before it - at which point recovery is pretty much impossible. By using safeguards such as the above and allocating memory before I begin processing, I can alert the user to a memory allocation problem before the processing has begun. Thus, my users can be relatively certain that a long operation really will succeed, rather than running out of memory at the last minute.
      • malloc has some notable bugs in it - it often hangs when allocating numerous small chunks of memory; when it does, no amount of exception handling will bring control back to your program. Because of this, it's actually better to allocate a large chunk of memory at the outset and parcel it out as the program needs it, rather than running the risk of hanging the machine with a large number of calls to malloc.
      When it comes down to it, every computer has limited memory. The difference between those programs written using a C++ String and a C-style string is that a program written uses c-style strings does not allow the programmer to forget that memory is limited. A C++ programmer, OTOH, will write as if there's no limit to memory, and hopes that someone won't process a particularly large file, or his program will crash. Unlike the C++ programmer, the C programmer must choose an algorithm that can work within a given space requirement, and hence, the size of the data processed becomes irrelevant - it simply takes more time, rather than segfaulting, or worse, hanging the machine.

      I could go on about how my university taught students to allocate memory but not to free it, but I'll spare you. I think the real problem is that the illusion of infinite memory is just that - an illusion. While the String types have some nice features, everything done with a String type can be done with C-style strings, and if it can't, it's usually trivial to implement. With C-style strings, I can formally prove the correctness of an algorithm, but not with the String types, simply because their behavior is not well defined for cases in which memory allocation fails. Even if these string types had a standard behavior, you're still left with an algorithm that becomes useless when memory allocation fails.

      And do you know for certain that the String type isn't immune to buffer overflow? If your program crashed because of excess input, would it escape back to a root-level shell? When it comes down to it, security requires more thought than just using some nifty-yet-formally-incomplete classes.