Software composition analysis (SCA) is a necessary tool that detects vulnerabilities within dependencies such as open source libraries. As the composition of modern applications has shifted from predominantly custom code to as much as 70-90% open source, managing vulnerabilities in dependencies from third parties has become more important than ever. However, while existing SCA solutions focus on dependencies in application code, they do not cover many other dependencies in software delivery pipelines like build modules (e.g., GitHub Actions), development tools (e.g., Jenkins), development tool plugins (e.g., ecosystem of plugins), and more.
Securing dependencies across the pipeline has received little attention thus far. However, it is believed that the SolarWinds’ attackers made their initial foothold by breaching an outdated and vulnerable version of a build server. Whether the vulnerable dependency is in the application’s code or the software delivery pipeline, both represent breach risks.
To align solutions with breach risk, not only must we broaden the definition of dependencies beyond application code, but we also must consider both prioritization and remediation. Traditional SCA tools cannot make this leap because they only understand development. They do not understand delivery pipelines or runtime environments, which inherently limits their scope.
This blog introduces the next generation of SCA, which we call Pipeline Composition Analysis (PCA). First we’ll explore what SCA is, where SCA falls short, and then discuss capabilities of PCA to better secure dependencies in modern SDLCs.
What Is SCA?
Software Composition Analysis (SCA) is a security tool that identifies dependencies in your application code and whether any vulnerabilities exist within those dependencies. It also identifies open source licenses in any open source libraries.
SCA scans have long been a staple of the pre-release security diet because they help determine what open source and third-party components and their associated licenses make up your software. This information helps organizations identify dependencies in their source code with known vulnerabilities. Since the vulnerable code comes from a third party, the practical fix is virtually always upgrading to a newer version in which the third-party developers have remediated the vulnerability. However, in complex code bases, upgrading dependencies isn’t always as straightforward as it would seem. Plus, vulnerable dependencies in application code are not always exploitable in runtime environments. This creates friction between development and security teams because developers naturally don’t want to spend time upgrading libraries that don’t actually pose a breach risk.
Why SCA Falls Short
The traditional SCA approach was pioneered in 2002. From 2011-2016, newer vendors brought a much-needed focus on integrating SCA with developer workflows. Despite this, the core product itself didn’t change. At the same time, however, the SDLC changed astronomically. With modern development practices, release velocity is higher, teams work more closely together, and organizations use more tools and third-party components throughout the development pipeline. This results in modern applications using a far greater number and variety of dependencies than ever before.
SCA tools focus only on application code. Application code may contain vulnerabilities, but dependencies exist in more places than just an application’s source code. Today, vulnerable dependencies commonly exist across the entire software delivery pipeline, including:
- Dev Tools (e.g., Jenkins)
- Dev Tool Plugins (e.g., Jenkins Plugins)
- Build Modules (e.g., Github Actions)
- Build Module Dependencies (e.g., GitHub Action libraries)
- Infrastructure-as-Code (IaC) Dependencies
Traditional SCA lacks visibility into these components and cannot determine whether they are vulnerable. Furthermore, traditional SCA can’t tell where a vulnerable component has been deployed or even if it’s been deployed.
Pipeline Composition Analysis Is Next-Gen SCA
PCA is an evolution designed to rethink and realign SCA with the actual risk that dependencies pose today to modern development pipelines. PCA improves upon SCA by including a deep understanding of the tools, configurations, processes, activity, components, and dependencies used at every stage of the delivery pipeline. While SCA addresses some of “what” is vulnerable, PCA completes the “what” and adds a new dimension: “where.”
PCA’s insight into the actual SDLC itself advances it beyond the limitations of SCA in several key ways including breadth of dependency coverage, rapid remediation via deployment locations, and prioritization based on runtime exploitability.
Breadth of Coverage: Securing Dependencies Beyond Application Code
A software dependency is any code that was written by a third party that an application relies upon. This is not a new definition, but the volume and variety of dependencies that modern applications rely on has increased massively since the first incarnations of SCA were developed 20 years ago. In addition to dependencies in application code, modern applications dependencies include the following:
The tools and infrastructure that makeup a software delivery pipeline are key dependencies. Source control management systems, build systems, registries, containers, and cloud environments all are third-party software that supports applications. Vulnerabilities in these tools are common sources of breaches that AppSec teams must begin to own.
Development Tool Plugins
Not only are development tools dependencies, but the ecosystems and marketplaces that many development tools offer are also dependencies that must be secured. A recent example was Jenkins announcing dozens of vulnerable plugins that needed to be updated.
The trend of GitOps is increasing the popularity of build modules such as GitHub Actions and GitLab Runners. These too are third-party code that can introduce vulnerabilities into your software supply chain in unexpected ways.
Build Module Introduced Dependencies
Not only can build modules themselves be vulnerable, but some build modules introduce additional dependencies that also need to be secured.
Infrastructure-as-Code Introduced Dependencies
Just like build modules, IaC files can also introduce other dependencies that AppSec teams need to account for and monitor.
Rapid Remediation: Vulnerable Dependency Deployment Locations
Vulnerable dependencies represent a higher risk of breach than custom code because once common software vulnerabilities become public, exploits follow quickly. This creates low-hanging fruit for attackers, and many organizations are targeted based on the ease of exploitation rather than on the value of their assets and data. This means that AppSec teams must react quickly to exploitable dependencies regardless of whether they consider themselves targeted by sophisticated attackers.
A critical capability of PCA is tracing the deployment paths of dependencies across all phases of the SDLC, from code to cloud. PCA can not only determine what is vulnerable but also whether it has been deployed and where it has been deployed. Log4Shell is the perfect example of this.
Log4Shell demonstrated that reacting quickly to new vulnerable dependencies is critical but not always easy – especially when fixing the underlying issue requires multiple updates. Knowing exactly where vulnerable dependencies are deployed is critical to increasing the speed of applying the fix and ensuring that all vulnerable instances have been fixed. Though traditional SCA can find defects in source code, identifying where the vulnerability has been deployed to production is a serious blindspot.
Prioritization: Exploitability in Runtime
While the speed of remediation is critical, not all vulnerabilities are actually exploitable in every runtime environment in which they are deployed. Developer time is precious and “remediating” false positives is obviously inefficient, so understanding whether a dependency is exploitable in the runtime environment in which it is deployed is critical.
While Log4Shell is a good example of a vulnerability that needed to be remediated quickly, Spring4Shell is an example of a vulnerability that probably does not need to be remediated in most production environments. In order to exploit Spring4Shell, the runtime environment must include:
- JDK 9 or higher
- Apache Tomcat as the servlet container
- Packaged as a traditional WAR and deployed in a standalone Tomcat instance (Typical Spring Boot deployments using an embedded servlet container or reactive web server are not impacted)
- spring-webmvc or spring-webflux
- Spring Framework versions 5.3.0 to 5.3.17, 5.2.0 to 5.2.19, and older versions
Given the low likelihood of these combinations, Spring4Shell’s complex exploitability highlights the importance of understanding all the components that make up the runtime environment. Since few, if any, organizations ever fix all of their vulnerabilities, prioritization is key to reducing AppSec risk, and nothing aids prioritization more than taking unimportant things off the list.
SCA Is Dead, Long Live PCA
PCA is a natural evolution in application security, representing the next generation of SCA. It delivers powerful security insights and is the backbone of any effective software supply chain security platform. Organizations benefit from implementing PCA as a means of detecting and remediating vulnerabilities throughout their development pipeline with fewer false positives compared with tools that fail to consider a deployment pipeline in its entirety.
Beyond traditional SCA, the benefits of PCA include:
- Breadth: Modern SDLCs depend on third-party code in all phases of development. PCA secures all dependencies, not just those in application code.
- Speed: Threats like Log4Shell require rapid and thorough responses. PCA understands where vulnerable dependencies are deployed, making finding and fixing them much easier and more auditable.
- Prioritization: Increases in release velocity increase the volume of security alerts while decreasing the time to remediate them. PCA understands development and runtime environments to understand when cloud components catalyze to trigger the exploitability of the vulnerable dependency.