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."

9 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 stevey · · Score: 3, Informative

      That's a good start, and all the 'n' functions are worthy - but it's worth thinking a level higher and being careful not to trust user/network/other programs as a source of input.

      A really good read is the Secure Programming Howto, but even that is just a start, security is a process not a product...

    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.

    4. Re:How to develop securely in 4 words by __past__ · · Score: 2, Informative
      Why not teach people to write correct code instead.
      Why not do both?
      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?
      Yes, in most cases, it is. Normally, I'd rather have a possible DoS than somebody writing in my stack.

      The String types dynamically allocate memory...
      This has little to do with the problem I was talking (well, at least thinking...) about. Of course, if you need to run in bounded space, dynamical allocation is not for you. Still, bounds checking would be nice.
      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.
      Even without bugs, mallocing lots of small chunks tends to be rather slow - which is indeed something many programmers tend to forget, treating malloc as an essentially cost-free operation. I have actually seen C code that became a lot faster after using a garbage collector - the mark-and-sweep phase was less overhead than what was gained by making allocation to little more than a pointer increment.
      When it comes down to it, security requires more thought than just using some nifty-yet-formally-incomplete classes.
      Of course. I'd still claim that some programming environments make it easier to introduce critical bugs than others, but nothing will prevent a non-thinking coder from messing things up big time. Look at all the PHP guys, they don't have buffer overflows (except in the PHP interpreter itself, of course), but they still manage to keep all their nifty web forums a frequent topic on the security mailing lists.
    5. Re:How to develop securely in 4 words by YellowElectricRat · · Score: 3, Informative
      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.

      Can't possibly fail, huh? Too bad if your char arrays don't turn out to be \0 terminated... Then you're in big shit. Hell, even strncat won't help here if 'string1' doesn't have a \0 terminator.

      Moral of the story - even if something "can't possibly fail", someone will still find a way to make it fail.

    6. Re:How to develop securely in 4 words by Anonymous Coward · · Score: 1, Informative

      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.

      Of course it can fail. It fails for the same reason the String classes can fail -- because you've run out of memory. The difference is that you fail when you run out of stack memory, not heap/virtual memory.

      For added interest, while your program may have up to 2 or 3 GB of virtual memory, limited by swap space, your stack is typically a more limited resource (by default, just 1 MB on Windows systems, though you can change this when the program is linked).

      Additional fun comes when your program generates an out-of-stack exception -- this is NOT a C/C++ exception, it's an OS level exception outside the runtime. Those are more trouble to catch, and require the try/catch and needless error checking you seem to disdain.

      If I'm writing a program that uses extensive memory resources, I have far more of those resources available to me if I use the String classes and the heap than if I declare local stack variables. And I'll use those classes rather than the C string equivalents, because I trust the classes to clean up after themselves more than I trust my own code, or my co-workers.

  3. If you have to ask by SHEENmaster · · Score: 3, Informative

    then you don't know enough about programming to be considered an expert by the rest of us.

    There's often an obsession attached to the definition by those of us that consider ourselves hackers. If you stay up until 4 am with school the next morning, working on a program for no profit or wage, you can consider yourself a hacker.

    Exceptions include VB programmers, or |-|@X0Z, and those that break into computers using exploits written by others, where targets are chosen because of apparent vulnerability, aka script kiddies.

    Breaking into computers is NOT an essential part of hacking, that's a misunderstanding by the media. Then again, is "ya'll" a valid contraction in the south-east?

    --
    You can't judge a book by the way it wears its hair.