At Sonar we are committed to helping you achieve a state of Clean Code. This means that your code becomes secure, reliable, accessible, and maintainable so that it is fit for development and production. Our Clean Code solution detects all kinds of issues as you code and our teams continuously research new innovations to provide the most comprehensive code analysis. For this, a deep understanding of all of your code is key.
Uncovering security vulnerabilities is particularly challenging because these issues can be complex and deeply hidden when your code uses and interacts with third-party dependency code. In this blog post, we are excited to share more about a major breakthrough in our detection of deeply hidden security vulnerabilities that traditional tools cannot detect.
Let’s have a look at these vulnerabilities, how we detect them, and how you can start using our deeper SAST today to clean your code!
The Problem of Hidden Vulnerabilities
Despite being known for decades, taint vulnerabilities (or injection flaws) remain a top security risk for applications. Popular types include SQL Injection, Deserialization, or Command Injection vulnerabilities whose exploitation can have dramatic consequences: Attackers can leak sensitive data, execute malicious code, or take over control of a software’s server. Even a single one of these issues ending up in your production code can put your business severely at risk.
But why do these critical code vulnerabilities still occur?
One of the main reasons is that these vulnerabilities can be very obscure to developers and are hard to spot. Typically, taint vulnerabilities do not manifest in only one code line but arise out of the interaction of multiple code sequences that are located in different code files and functions. Each code sequence itself can be harmless while the combination leads to a security issue. The more code from different locations is involved, the harder it becomes to comprehend its interactions, effects, and ultimately its security implications.
Things are getting even more complicated when third-party code is used. Nearly all software use - depend on - multiple open-source frameworks or libraries. This enables developers to reuse existing code and to focus on delivering new features fast. However, this comfort also bears its risks.
Whenever you leverage a dependency in your project, like the Spring framework or Log4j library, your code is interacting with that dependency's code. And just by that interaction and unique combination with your code, a new security vulnerability can arise, as we have seen by the infamous Log4shell vulnerability. Manually reviewing your own codebase is already challenging enough. Additionally reviewing all the code of the features used from dependencies and their subsequent interactions with their own – also called transitive – dependencies is impossible.
Traditional Approaches
Static application security testing (SAST) can help you automate a code review. With techniques like taint analysis, the code interactions within your project are evaluated for security issues with varying coverage, accuracy, and speed. However, all traditional SAST tools scan only your project code. These tools are unaware of the dependency code and their security-relevant interactions, except maybe for a few manually added tool configurations. Such hard-coded knowledge is inherently incomplete: In reality, hundreds of thousands of different dependencies and interactions exist in each language’s ecosystem that cause blind spots for traditional SAST tools. Whenever your code interacts with a dependency, traditional SAST tools understand only a fraction of the code actually executed and, as a result, miss deeply hidden vulnerabilities.
Such hidden vulnerabilities are also not detected by Software Composition Analysis (SCA). SCA tools report issues in dependencies based on a database of publicly known vulnerabilities. This database is the limit of what can be detected by SCA. Considering the billions of frequently updated code lines available in open-source dependencies, the amount of publicly documented issues found in a SCA database is extremely small. Moreover, just because a dependency feature can potentially be used insecurely by an incautious interaction from your code, it does not mean that the dependency is vulnerable itself. It is up to you as the developer to interact with the dependency securely in your code. A SCA database will not list a unique vulnerability that is caused in your code and, hence, it will be missed by SCA.
Sonar’s deeper SAST
To address this critical gap in the market, we are proud to launch deeper SAST. We managed to expand our precise taint analysis capabilities from project code deep down into transitive dependency code. This enables developers to identify deeply hidden taint vulnerabilities arising from the interaction between their code and its dependencies.
Let’s have a look at two concrete examples of a deeper SAST issues. For simplicity of this blog post, we use vulnerabilities with only a few code sequences and interactions but keep in mind that these are significantly more complex in real-world code bases.
The code snippet below shows a Deserialization vulnerability. The code fetches data from the Session-Auth HTTP header [1] and then tries to invoke Java objects based on this data [6-8]. Since any HTTP header can be manipulated by an attacker, the Java objects can be malformed which enables an attacker to gain remote code execution.
Open deeper SAST issues in SonarCloud
For deeper SAST, the critical step happens in [3]. The function decodeBase64() from a library is used to process the data. If a SAST tool is not aware what this library function is doing in [3], it cannot make the connection between [1] and [8] and will miss this critical vulnerability.
Let’s have a look at another example code shown below. This time, the code snippet performs a database migration for a specific user. It retrieves a user-supplied username [1] that is used as part of the name of a database savepoint [7]. The savepoint is created by using a library's function with the innocent name setSavepoint() [8]. Little does a developer, nor a traditional SAST tool, know that this particular function is susceptible to SQL injection. An attacker can inject a malicious user name with SQL syntax into the savepoint in order to modify the database query. We even reported this to the library's maintainers who fixed the vulnerability and are tracking it as CVE-2023-22102.
Open deeper SAST issues in SonarCloud
Today, deeper SAST is available for Java, C#, and JavaScript/TypeScript and already supports thousands of the topmost and commonly used open-source libraries, including their transitive dependencies. All different types of taint vulnerabilities that we support are enhanced by deeper SAST. Our SAST engine’s leading precision and performance stays the same when analyzing source code with dependencies and no additional steps are required from users to benefit from our deeper analysis.
So far, we observed that on average for every 10 regular vulnerabilities found in a code project, our deeper SAST detects one additional, deeply hidden vulnerability. We will expand our deeper SAST to detect even more hidden vulnerabilities by covering many more dependencies and languages, and by continuously improving our taint analysis.
Behind the scenes of deeper SAST
Let’s have a look at how Sonar deeper SAST works at a high level. Our innovative approach comprises two parts.
First, internally at Sonar, we gather the source code of the most popular open-source dependencies. We then use sophisticated code analyzers to extract all code information from these dependencies relevant to our taint analysis. One of the key challenges is to scale this automatically to thousands of dependencies, their transitive dependencies, and different versions.
Relevant information includes, for example, knowledge about sources of user input, data flows, or security-sensitive operations. Note that we do not look for vulnerabilities in dependency code but for possible interactions that can make your code vulnerable. The extracted valuable information is then stored in a knowledge base that can be further optimized. This knowledge base is continuously updated to stay ahead of important changes in the ecosystem.
Then, the knowledge base is integrated into our taint analysis that is shipped in our products. When your code is scanned, our taint analysis now has the unique ability to understand code interactions between your code and dependencies’ code by inferring missing knowledge from our comprehensive knowledge base. This way, dependency interactions can be understood and evaluated in your code’s context for security implications, leading to uncovering deeply hidden security issues.
Try it out
The best thing is: deeper SAST comes at no additional costs for our users. You can try it out using SonarCloud, our cloud-based offering that is free for open-source. When you are using SonarQube (self-managed), deeper SAST is available in the Developer Edition version 9.9 LTS or higher. Our Clean Code solution enables you to continuously inspect and analyze your codebase for over 5,000 rules using quality gates to determine if code meets the defined standards for production.
We have created a demo repository that you can use to see deeper SAST in action. In this Java Spring application, various hidden vulnerabilities can be found when forking and scanning this project. You can find all instructions to get started in the links below.
Interested? Try deeper SAST