Even when used with the best analysis tools, fuzzing will not provide perfect code coverage. For your most security-critical applications, you may need to go further.
In Part 1 of this series , we introduced the software verification technique called fuzzing. We described what it is, who uses it and why, the tools involved, and the benefits of fuzzing.
In Part 2 , we examined the limitations of fuzzing and how most of them can be overcome by pairing a good fuzzer with formal-methods-based analysis tools.
This post is Part 3 of a 3-part series derived from TrustInSoft’s new guide to fuzzing for cybersecurity entitled “Fuzzing and Beyond.” To obtain a FREE copy, CLICK HERE.
Fuzzing is a great first step toward eliminating undefined behavior in your code.
However, for applications where security is key and you want to be absolutely sure your code is totally free of all vulnerabilities that can be exploited by hackers, you’ll need to go beyond fuzzing.
In interpreter mode, the Analyzer makes iterative test runs on the discrete input sets it has been given. But, as we’ve already seen in Part 1 and Part 2 of this series, the input space for most software applications—consisting of billions upon billions of possible combinations—is too immense to be covered completely through iterative testing. If you try, you’ll never finish.
For applications where assurance of a high level of cybersecurity is required, TrustInSoft Analyzer offers a more advanced solution. As we’ll see shortly, this solution is a complement to fuzz testing that can guarantee perfect cybersecurity. We call this solution exhaustive static analysis.
Exhaustive static analysis goes beyond fuzzing. Instead of performing individual executions on individual inputs in an iterative fashion, it relies on a formal method called abstract interpretation to fully explore a program’s input and execution space.
This input generalization works for all variable types in C/C++: integer, float, pointer, function pointer, etc. You can easily generate a generalized test from one of your existing tests with discrete inputs or from your API interface.
Thanks to the power of mathematics, exhaustive static analysis allows you to run the equivalent of billions upon billions of test cases simultaneously in just a few seconds, in a single test run. It is guaranteed to detect all undefined behaviors in your code, regardless of compilation optimization level or memory layout. Plus, once all the bugs it detects have been eliminated, it provides formal proof that your code is totally free of exploitable vulnerabilities.
At this point, you may be asking yourself, “So, if you can eliminate every last vulnerability with exhaustive static analysis, why use fuzzing at all in the first step?”
Having said that, when it comes to the type of software where both Fuzzing in interpreter mode or exhaustive analysis techniques are suitable, sometimes it can still be more efficient over the entire test campaign to start initially with fuzzing in interpreter mode and then move in the second stage to exhaustive static analysis.
The second way, which we prefer, is to re-tune and repeat your analysis and then compare results.
By tuning, we mean adjusting the approximations of the acceptable and forbidden zones with slightly different parameters—to change their “shape,” if you will in order to eliminate false positives.
Now, you’ll remember that TrustInSoft Analyzer’s interpreter mode will automatically run any set of inputs automatically and generate no false positives. That’s why we called fuzzing with interpreter mode a great first step. By first fuzzing your program with AFL and running the resulting fuzz inputs through TrustInSoft Analyzer in interpreter mode, you can quickly detect and eliminate many true vulnerabilities before running the Analyzer in exhaustive static analysis mode.
Interpreter mode thins your vulnerability herd considerably. This greatly simplifies the task of re-tuning your analysis. It makes the elimination of the hard-to-find undefined behavior that exhaustive static analysis reveals much easier and quicker. Ultimately, it saves you a lot of time over the course of your debugging campaign.
You’ll achieve formal proof that your code is 100% vulnerability-free much, much sooner.
In today’s world, software providers need assurance of a high level of cybersecurity in their source code. To do this, there are several significant advantages to proceeding to exhaustive static analysis after fuzzing in interpreter mode.
First, it’s exhaustive. You’ll have peace of mind knowing you have found and removed every undefined behavior—every single vulnerability from your code.
Second, once you’ve removed all undefined behavior, TrustInSoft Analyzer provides a mathematical guarantee that you’ve removed every vulnerability from your code. This is formal proof you can use as evidence in reviews with security specialists, customers, and regulators.
Finally, having accomplished exhaustive static analysis once for a given program, you’ll find it is much less work than fuzzing when you modify your code. You’re now working from a much cleaner baseline. You simply re-run the analyses you’ve already set up.
This post is Part 3 of a 3-part series derived from TrustInSoft’s new guide to fuzzing for cybersecurity entitled “Fuzzing and Beyond.” To obtain a FREE copy, CLICK HERE.
This post concludes our series on fuzzing. If you found it useful, our new white paper, Fuzzing and Beyond, contains still more information on the use of fuzzing and exhaustive static analysis for making your code more secure. You’ll discover why fuzzing and exhaustive static analysis with TrustInSoft Analyzer form an efficient two-step process for securing your most critical code. You’ll also learn of an additional benefit fuzzing provides. You’ll even find two case studies on how TrustInSoft Analyzer formally verified the total eradication of security vulnerabilities from two highly sensitive applications.
To download your FREE copy, CLICK HERE.