The promise of static analysis is compelling but our most frequently-asked question is, "Where do we start?" Security is a top-of-mind concern, so we are also frequently asked questions such as, “How vulnerable is our software and how do we start to fix it?” This post describes a reasonable starting point and process for understanding your current vulnerabilities and adopting static analysis as part of an ongoing improvement process.
- Performing a Security Audit with CodeSonar (Video)
- Performing a Security Audit with CodeSonar
- Don’t trust any input! Prevent vulnerabilities from becoming exploits with tainted data analysis
Where to Begin with Static Analysis Tools for Security Audits
As with any automated software tool, it’s important to know what you’re looking for. In the case of discovering a system’s vulnerabilities, a security audit makes sense. This does require some manual homework ahead of time -- for example, if a system doesn’t have a formal threat analysis, it’s a good time to consider doing one. Understanding the threat environment and attack surface of your system is critical in a security audit.
Threat Model and Attack Surface
The probability of a cyber attack affecting a device is a function of both the attack's potential impact and the attack being possible. A threat assessment is performed in order to establish a threat model and attack surface, by looking at the motivations and intents of potential attackers, their possible avenues to attack your system, and the probability of them being successful in that attack:
- Attack sources and motivations - Threats can be insiders, activists, terrorists, criminals, state-sponsored actors, or competitors. Understanding the sources of attacks and their motivations can help you understand the goals of an attack and whether such a group could achieve the attack.
- Roles and privileges of authorized users - Identifying users and their access rights is essential to enforcing a key security principle of least privilege. Limiting access of operational users to prevent dangerous operation or leakage of important data prevents insiders and attackers from gaining more than their privilege level allows.
- Identification of potential electronic attack vectors - Typically, network connections and other peripheral I/O provide intrusion access to attackers. In some cases, the attack vector may be internal from local access to the user interface or local area network. In other cases, access via a wide area network or even the Internet is a possibility.
- Assessing attack difficulty - The loss assessment indicates which services and functions would have the most impact if attacked. The relative difficulty of these attacks must be evaluated based on the attackers and their intrusion vector.
- Assigning a threat metric - It's not possible to foresee every attack, nor is it efficient to attempt to protect against every possible attack. Attacks from outside the defendable network segment, for example, that have a large impact and a low attack difficulty would have a high threat metric. Scoring each combination of source and motivation, attack vector, and attack difficulty is required.
A thorough threat assessment yields an understanding of what external interfaces are the biggest threats for attack. This information pinpoints which interfaces and types of tainted data (from input) allow security vulnerabilities to be exploited. Detecting vulnerabilities in source code, including potenitally hazardous data flows, is particularly well suited to advanced static analysis tools. Knowing which interfaces need to be analyzed (for example, network) helps narrow the scope of the analysis.
Configuring Static Analysis Tools
Advanced static analysis tools such as GrammaTech CodeSonar ship with a set of default warnings and errors. These are the most critical and useful quality and security defects that customers need; however, these are not always the most relevant to an individual case. When performing early security audits, it’s more important to narrow down the analysis in order to create a reasonable amount of errors and warnings for evaluation. This is done by adjusting the following parameters:
- Warning Classes: Most static analysis tools allow for turning on or off checkers and warnings. The default settings are likely not ideal for a security audit. Enabling the key error classes and limiting the non-essentials is recommended.
- Tainted data types: Not all sources of data are potential attack vectors or present in all systems. For example, network sources of data are common for connected devices, but user or file input may not be – the thread analysis and attack surface gained from the previous step is important here. Trimming the analyzed sources reduces false positives and number of reports.
- Uninteresting Code: It’s possible to limit the subsystems to analyze and remove unwanted code from the analysis. The tools don’t understand the intent of the software so trimming the applicable code manually focuses the analysis on key parts of the system.
- Thoroughness versus time: The depth of analysis is sometimes tunable and should be set to the highest settings for a security audit. It’s important that the analysis is as complete as possible before taking action with regard to discovered vulnerabilities.
Narrowing the analysis to the high-priority vulnerabilities is important to provide a first-look at security readiness. These parameters can change over time to provide a more complete audit, as shown below.
Figure 1: A simple process for adopting static analysis tools for security audit and ongoing security improvement.
Using the narrowed set of results configured in the previous step, the analysis begins. Prioritizing the results further focuses the work on critical vulnerabilities. For example, buffer overflow errors are likely to be considered more critical than a coding-style warning. Therefore, the recommended approach is as follows:
- Prioritize: Rank the errors in terms of relative priority before analyzing their validity. It’s possible to have false positives in reported errors, but to save time it makes sense to only analyze the highest priority ones first. Lowest priority reports may not need checking at all (meaning they likely should be disabled as above).
- Evaluate: Checking the error reports from the tools in priority order is required at this stage. Serious errors and their corresponding dataflow should be checked in detail. Tools such as CodeSonar provide detailed reports to assist in verifying each error with the ability to mark as false or true and provide annotations as needed.
- Annotate and Report: Most advanced static analysis tools provide reports of each analysis run on the source code. After critical vulnerabilities have been validated and annotated, a source code security audit is ready.
A completed security audit can be used for further risk management, fixing and testing, and for comparison against subsequent versions of the software. It’s critical that static analysis become part of an iterative approach to security improvement.
Static analysis tools are a powerful weapon that helps to improve security, but adopting the tools and creating a starting point for your development team might seem daunting at first. Understanding the aims and goals of your security audit and threat assessment can narrow the focus, making the analysis results relevant and useful. Configuring the tools and prioritizing the results help streamline the audit process, resulting in actionable results.