Actionable intelligence for software security
Niroshan Rajadurai of Vector Software explains how to use dynamic analysis to prove that security issues and vulnerabilities exist in today’s embedded environments.
It’s a commonly held belief that applying static analysers alone can help spot and eradicate common security issues. However, with the high number of false positives reported when using static analysis, it makes knowing if you have detected a real error a time consuming process, and the mitigations put in place might have just hidden the error under a false negative. But what are the alternatives?
Dynamic analysis can be used for detecting potential vulnerabilities in today’s embedded environments. And pairing dynamic and static analysis creates ‘actionable intelligence’ for developers, and allows them to quickly ascertain the absence of obvious reliability issues.
We have all come to terms with the idea of a connected world of devices, falling under the heavily used moniker of the ‘Internet of Things’ (IoT). As we contemplate a world where every device is connected to the internet, there are growing concerns about the security of both the endpoints and their centralised control systems.
By 2020, industry analyst Gartner predicts that IoT endpoints with secure elements, both standalone hardware and software based, will grow from the 103 million installed in 2013 at a CAGR rate of 33.4%, reaching a global population of 775 million. Many of these devices will be in embedded systems within devices and equipment.
Above: When static analysis may overlook an issue
However, as a consequence Gartner also predicts that 25% of identified security attacks in the enterprise will involve IoT devices and that even by 2018, over 50% of IoT device manufacturers will remain unable to address threats emanating from weak security practices.
Security vulnerabilities can enter a product as soon as the first few lines of code are written, and the real danger is that they are not detected until much later. These vulnerabilities may represent serious issues, which may only be exploitable when run on the physical device or are deployed in the field.
Consequently, developing high quality, secure applications requires constant vigilance in all stages of development. This means using tools that are capable of detecting possible vulnerabilities when writing code, integrating modules and testing compiled binaries on target hardware.
Adopting a static analyser is good in theory, and it is common for developers to want to know the following tenets: a) do we have any issues, b) how many and c) what and where are they? Assessing the code with a static analyser will give you some direction, but this is not the catch-all solution, especially when security is at stake.
Static analysis tools analyse syntax, semantics, variable estimation, as well as control and data flow to identify issues in the code. Usually rule-based and run late in the development cycle, the results from static analysers when used alone can create potential false positives that can mean the real error is hidden under a false negative.
In the example, which was taken from the open source web-server that powers part of Wikipedia, we have a code sample which contains a potentially exploitable NULL pointer vulnerability. While one of the inputs is checked if it is null, the other is used without such assurances. In tests with some common open source static analysis tools, this issue was overlooked, whilst the commercial analyser, Lint, reported it as only a possible error. However, using a dynamic analysis tool, it immediately found the segmentation violation, which, if left unmitigated, could have been exploited, leading to unwanted business impact.
Dynamic analysis in addition to static analysis can pay dividends. Dynamic program analysis is different as it is performed by executing programs on a real, or simulated, processor architecture. This way of testing software simulates the program with enough test inputs to replicate real world and exceptional conditions, so its behaviour can be observed and checked for security weaknesses.
There is a highly regarded community developed formal list, known as ‘Common Weakness Enumeration’ (CWE) that serves as a common language for describing software security weaknesses in architecture and code, and is a standard, common lexicon for tools detecting such potential weaknesses.
Above: An example of another error, highlighted in Vector Software’s ‘Analytics Dashboard’
In the CWE taxonomy, there are numerous weaknesses where the use of dynamic testing can highlight vulnerabilities, in particular anything with hard errors such as the use of null pointers, buffer over- or under-runs, and stack overflows.
In the figure on page 13, Vector Software highlight an issue found in the code of one of its automotive customers. In this code, various checks were made against a variable, but it was then still used in the denominator of a mathematical expression. Again, left unguarded against, this could have a real-world business impact. While static tools can only suggest on the potential of such errors, with dynamic analysis a test can be constructed that immediately demonstrates the vulnerability.
Every development team needs a process to achieve its application security goals. Developers need to consider that there are three stages to creating a system to manage detecting vulnerabilities. Firstly, build a full portfolio of all the components/modules in the application including any legacy code and third party code, and baseline them to understand what has been tested and what needs to be done. Secondly, once the data is collected developers need visibility of any vulnerabilities in the application through executing static and dynamic analysis. This will allow developers to then understand the risks present in the application.
Finally, from this point on, developers can set about increasing the amount of code coverage, giving visibility of the quality of their software. The benefit of all this work is that the application is now easy to maintain and any changes to the code can be retested in the shortest possible time.
In conclusion, development teams need to understand that no single tool fits every circumstance, and the most pragmatic approach is to use multiple tools. Static analysis has its place, but dynamic execution can find certain vulnerabilities more definitely and together will create a more secure product.