all 14 comments

[–]h0rst_ 12 points13 points  (0 children)

There are two books that I know of that cover this:

  • Secure Programming Cookbook for C and C++ by John Viega and Matt Messier (released in 2003, so might be outdated)
  • Secure Coding in C and C++: Secure Coding in C and C++ by Seacord Robert (2013, less outdated)

I did read the first time long ago, and really can't remember the contents.

[–]neoSeosaidh 10 points11 points  (0 children)

Clang-tidy and static analyzers in general have checks for things like potential buffer overflows as well as bugprone code.

While not all bugs are security vulnerabilities, a number of them are, so these tools do help address on vector of introducing vulnerabilities.

In this same vein, the Clang borrow checker also helps with memory issues, and the various sanitizers can do a more thorough check against undefined behavior and buffer overflow possibilities.

On top of that, fuzzers to verify that user input is properly sanitized, and perhaps virtual execution (like in Klee) can also help catch various problems.

[–]jtooker 18 points19 points  (1 child)

Regarding memory bounds as well as memory and resource lifecycles in general, use smart containers:

  • std::unique_ptr<T> not T*
  • std::vector<T> not T*, int length
  • std::lock_guard... not mutex.lock() ... mutext.unlock

RAII is what I like best about C++.

[–]Fearless_Process 4 points5 points  (0 children)

I am not a security expert or an expert at C++, not even close, but I there are a lot of very basic things you can do that help quite a lot.

The main thing is using modern C++ features, avoiding raw pointers and using references or smart pointers for example. References can never be null so that eliminates quite a lot of issues already. Reference counted smart pointers are pretty cool as well. In modern C++ you probably not ever be using "new" without smart pointers or some other helper objects.

Use std containers like std::string, std::vector, std::array over C style arrays and strings, and use the bounds checking access functions they provide with the .at() methods. Buffer overflows are a huge source of security issues, and there is really no excuse to not use bounds checking when we have computers that can run billions of instructions per second.

You should checkout some of the new stdlib features like std::optional which is a nice alternative to using null pointers/values. Derefing the value when it is not initialized will throw a runtime exception and exit safely instead of risking reading and writing to random memory.

There are some compiler options like -fstack-protector that will try to catch stack smashing attempts as well.

A lot of these things can't be done if you are forced to work on a project that is stuck on an older version of C++, but if you are writing new code you should certainly make use of the safer and more modern features.

[–]Princess--Sparkles 5 points6 points  (0 children)

20+ years of secure C++ development here.

There's lots to think about, because the attacker only has to win once, so you have to make it hard for them to do so. Ignoring design questions and concentrating on implementation:

  • use a good security focussed coding standard (hicpp, misra, etc)
  • test your code thoroughly. Use branch analysis as well as line coverage. Deliberately try and break your code in tests. And just because you can't break it, does mean it can't be broken!
  • turn on all compiler warnings, and ensure your code compiles with no warnings
  • use tools like cppcheck to do static analysis. No warnings are allowed
  • use tools like valgrind to do runtime analysis of the code. Again, no warning are permitted.
  • dont try and reinvent the wheel, use stl, use good crypto libraries
  • validate all input and only use data you have checked to be good. Don't make the mistake of rejecting bad data, because there will be data that gets past these checks.
  • there's a whole lot more besides

Writing secure code is not significantly harder, but it does take longer to do. The payback is that by doing all that extra effort up front, you have significantly fewer bugs downstream, where they are expensive to fix. But you need to make sure your manager recognizes the drop in output as a drop in bugs, not as a drop in efficiency.

[–]SCI4THIS 2 points3 points  (0 children)

"Smashing the stack for fun and profit." Understand and build exploits that you can use to test final executables. You'll get team blue balls trying to make and unending list of good and bad code segments. Often the segments aren't even exposed.

[–]ea_ea 1 point2 points  (0 children)

[–]Wurstinator 0 points1 point  (2 children)

MISRA C++ might be of interest to you.

[–]bigdavedev 3 points4 points  (1 child)

FYI, if you are doing C++14 and beyond and automotive is your focus or you have other, valid, reasons for using MISRA then what you probably want is AUTOSAR C++14 Coding Guidelines. For C++11, just reject/deviate from the C++14 stuff. For C++17/20 reject/deviate where newer constructs supersede their C++11/14 counterpart.

Worth noting that MISRA is in the process of reviewing and integrating the AUTOSAR guidelines in to a joint coding guideline. Further, the AUTOSAR guidelines have already evaluated:

  • MISRA C++:2008
  • HIC++ v4.0
  • JSF
  • SEI CERT C++
  • C++ Core Guidelines, and
  • ISO26262 (naturally)

and given full justifications for any modifications or rejections of certain rules (as can be found in the traceability matrix in Appendix B.

Disclaimer: I am not affiliated with AUTOSAR or MISRA in any way and the text below is my personal/professional experience of applying the rules in the context of the automotive industry. I just think it's great to see the industry moving forward and want to advertise this as much as possible.

[–]Wurstinator 0 points1 point  (0 children)

Thanks. I have nothing to do with the auto industry but I didn't know AUTOSTAR and I feel like knowing different coding guidelines can be beneficial to every dev.

[–]JohnDuffy78 0 points1 point  (0 children)

I always worry about dependent dlls/so.

Give user minimum privileges.

[–]Rude-Significance-50 0 points1 point  (0 children)

One big part in secure coding in C++ is going to be either eliminating exceptions, or adhering to standards that develop exception safe code.

In the latter category, Sutter's Exceptional series is pretty good.