Best Practices for Automotive Software Testing
In this coding session, Khaled demonstrates the benefits of continuous fuzz testing for automotive software.
Common Challenges of Fuzzing Automotive Software
Due to the new ISO/SAE 21434 many car manufacturers (OEMs) are expanding their software testing activities. The standard contains regulations for software devices within vehicles, as well as their connectivity to external systems. This ISO recommends OEMs to integrate feedback-based fuzz testing into their DevOps processes and defines new requirements for software security engineering. In this coding session, you will learn how to benefit from modern fuzzing as part of your CI/CD workflow.
What Is the Best Way to Implement Fuzzing for Automotive Software?
As I deal with automotive customers on a daily basis, I see three main challenges that developers and security teams face when implementing fuzzing for their automotive software.
Where to start fuzzing?
When developers implement fuzz testing for the first time, they often start with a low budget, with little to no fuzzing experience, and no professional support. Besides, they often feel a lot of pressure that their first fuzzing project must deliver great results. Therefore, it is critical to choose the right project to start with.
How to fuzz complex systems with dependencies?
Infotainment systems in modern vehicles usually communicate with a whole range of external sensors. The code gets messed up and complicated very quickly. The dependencies in the software make it difficult for developers to fuzz the applications properly, and the manual effort remains very high. Therefore, your long-term goal should be to fuzz the application continuously and to simulate the input from those embedded systems simultaneously. This way, you will be able to automate your testing process far more than you could with traditional DAST or IAST and achieve a higher level of code coverage.
How to integrate fuzz testing into the I/CD?
Integrating fuzz testing into the CI/CD can help scale the benefits of this method. But for successful integration, communication is key. Developers, security professionals, and managers should be on the same page about the implications of these changes and how they affect certain processes. My Recommendation: Start Simple
Start from simple and proceed to more complex challenges. Developers sometimes tend to begin with the most complicated tasks or the one that promises the most bugs. However, I have experienced that when it comes to fuzz testing it is often better to act differently.
For instance, I would always advise starting to test automotive software with a simple C/C++ library that already got fuzzed by your security experts. With this strategy, you can understand the fuzzing process better.
Fuzz testing usually eventually finds a number of new bugs in these already tested C/C++ libraries, even if you considered this code as safe.
(Great, a first success! But please don't forget… there is also a human component to automated bug finding.)
Roadmap to Successful Fuzz Testing for Automotive
I would always recommend automotive developers implementing fuzz testing in three simple steps. With each step, you will become more confident and more proficient in what you do. This way you will get the bests results. And each little success will lead you to even more advanced fuzzing approaches that help you make your software more secure.
Roadmap and best practices to successfully fuzz automotive software (click to enlarge)
Step 1: Unit Fuzzing
When initially setting up fuzz testing in an automotive environment, the easiest way to do this is using pre-existing unit tests as a sort of template. In most projects, these unit tests already exist, since many automotive developers use unit tests to test the functionality of their software.
During the first hours after setting up the fuzzer, you will usually find the majority of security issues, just by testing with these self-contained units. Ideal candidates for these low-hanging fruits are libraries, API functions, and different kinds of parsers.
In this stage, you can also set up a continuous integration very easily, by simply repeating this already defined procedure at every upcoming merge request (similar to DAST or IAST).
Step 2: Interface Fuzzing
On the network level, fuzzing requires more efforts as different network interface protocols have to be taken into account (TCP/IP, Ethernet, CANBus, etc.). To simulate this, the fuzzing engines have to be able to understand certain protocols, such as IPSec, UDS, and Protobuf. That's why, interface fuzzing can take several days to weeks, but as the complexity increases, you will also find more bugs.
If you would start with interface fuzzing before unit test fuzzing you would most likely also detect all the findings that you could detect with unit test fuzzing. However, it might take you more time to debug and analyze the bugs when they are found via interface fuzzing. Therefore, it's usually better to start with unit fuzzing first.
Step 3: System(-like) Fuzzing
Especially in automotive and complex embedded projects, system fuzzing is the long-term goal. At a certain point, all tests should be connected to the hardware to find out what actually happens on the operating system with the commercial compiler. Luckily, it's possible to simulate the input of those systems. The simulations built during unit testing can serve as a fundament for testing the actual hardware.
See the Process in Action!
I hope this coding session gives you an idea of how to implement feedback-based fuzzing into your development process. However, the best thing is to see the process in action. So I provided you a recording of my coding session. Feel free to reach out, and to leave comments or feedback!
Get the Recording
Related Articles and Use Cases
Read more on automated security testing and fuzzing embedded software in tech Blog.
In modern vehicles, the security of human beings is a top priority. Learn more about how it can be ensured through advanced software testing.