How Do You Know Your Code is Secure?
bvc writes "Marucs Ranum notes that 'It's really hard to tell the difference between a program that works and one that just appears to work.' He explains that he just recently found a buffer overflow in Firewall Toolkit (FWTK), code that he wrote back in 1994. How do you go about making sure your code is secure? Especially if you have to write in a language like C or C++?"
0) Don't "roll your own" security unless absolutely necessary. Find someone else's implementations and work with those.
1) Design the code for security, code to that design. I've seen of security bugs creep into code because it was never designed to be secure.
2) Use static code checkers--such as Splint for C/C++ and FindBugs for Java--that look for security vulnerabilities.
3) Peer reviews/code audits. Sit down with your code (and have others who know how to look for security vulnerabilities sit down with your code) and do a full review.
Nothing is foolproof, but every little bit helps. It should be noted that all of the above also improve the overall quality of the code and reduce the number of overall bugs: Finding existent implementations of features that can be used can reduce maintenance and reduce bugs; Designing the code and putting it through a proper design review can catch a lot of logic problems and ensure that the code fits the requirements list--I've seen a huge number of synchronization bugs in Java simply because the author didn't know how to use synchronization properly; static code checkers find a lot more than just security bugs; and Peer Reviews/Code Audits can help isolate a variety of problems.
Integrate Keynote and LaTeX
By using valgrind. It's a virtual machine of sorts that runs your code and checks for any memory problems at all, including use of uninitialized memory. Combine that with thorough test cases, and you can be virtually assured that you have no memory errors in your C/C++ code.
However, security is a lot more than buffer overflows... but at least it brings you up to the relative security of Java, with speed to boot.
Open Your Mind. Open Your Source.
Unfortunately stl isn't binary compatible. That means you have to make sure you've compiled with exactly the same version of the stl with all the components of your program which accept and pass strings. This in turn makes it impossible to release different parts of your program separately from each other if you are using the stl at the interface between your components.
There are a couple of solutions to this problem:
1.) Pass character arrays at the interfaces between your components and immediately put those character arrays under the control of your library once they come in.
2.) Write or find your own string library and pass that string class between program components. Be careful when doing this. Mistakes will come back to byte you.
All of it's kind of nasty. It'd be nice if C++ could standardize their binary representation, even if it's only a standard valid per platform.
Then there's also:
3.) Choose a language which unlike C++ already has a standardized binary representation for strings, or a system global interpreter for a varying binary representation. This is just an extension of the "higher-level library which does the memory management for you" option really.
Don't get me wrong -- I'm agreeing with the parent post. I'm just adding a caveat.
Grammar tip: "Effect" is a verb. "Affect" is a noun.
Um, how's that?
Your poor grammar has a chilling effect on me. If I were you, I'd find a way to effect an improvement in your knowledge. Luckily it affects me only a little. But the fact that so few seem to understand that these two words are both verb and noun leaves me of sad affect.
Those bugs aren't harder to track down than "old-style" bugs, in fact I think they're vastly easier to track down than, say, a wild pointer. The difference is that you're less experienced at dealing with the new problems, so they seem harder to you. With time and practice, you'll see through copy/reference errors quickly. In the meantime, a little discipline can cover your lack of experience -- never store raw pointers in collections, always "objects". If you don't want to create copies, then store objects of a smart pointer class. In fact, avoid ever using raw pointers at all. *Always* assign the result of a 'new' operation to a smart pointer (auto_ptr works for a surprisingly large set of cases, but you may have to get a reference counted pointer type or similar for others -- the BOOST library has some good options if you haven't already rolled your own).
If you really run into different behavior with different compilers, then at least one of the compilers is buggy. That does happen, but it's a lot rarer today than it was a few years ago. When you find that situation, wrap the tricky bit behind another abstraction layer and implement compiler-specific workarounds so that your application code can just use the abstraction and get consistent behavior. In most cases, someone else has already done this work for you. Again, look into BOOST.
Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.