How Spectra Assure scans static dependencies
In modern software development, applications are rarely built entirely from scratch. Instead, they rely heavily on external libraries and frameworks that provide critical functionality, such as networking and data processing. Managing these dependencies is essential to ensure reliability, security, and compliance with licensing requirements.
Most dependencies are linked dynamically, meaning they remain as separate files in the runtime environment, which simplifies applying updates. This also enables SCA tools to quickly identify the versions in use and flag any known issues.
However, when a dependency is statically linked, library code is compiled directly into the applicationβs binary. This produces a self-contained executable but obscures which libraries (and which versions) are included. As a result, vulnerabilities hidden in statically linked libraries become a blind spot. This means that the application inherits the risk from the dependency, and remediation requires a full rebuild and redistribution of the binary. For organizations facing audits, compliance obligations, or supply chain regulations, this lack of visibility poses a serious issue.
Spectra Assure addresses this challenge by diving deep into the software and uncovering all of its components and dependencies, regardless of how they are linked. By generating accurate Software Bills of Materials (SBOMs) and shining a light on every part of the software, Spectra Assure helps organizations reduce risk, simplify compliance, and maintain trust in the applications they deliver.
This page explains what static dependencies exactly are, how they're identified with Spectra Assure, and where to find them in various Spectra Assure products.
What is static linking?β
Static linking is a process in which a linker combines any external libraries with the application code into a single executable file at the end of compilation. This means that all necessary code from external libraries is incorporated into the application itself, eliminating the need for those libraries to be present at runtime. Such libraries are then referred to as static dependencies.
This approach ensures portability and independence from the systemβs environment but also comes with drawbacks related to file size, memory use, and update flexibility.
What is the difference between statically and dynamically linked dependencies?β
To help you understand the benefits and drawbacks of static and dynamic dependencies, the following table lists the key differences between them:
Static dependency | Dynamic dependency |
---|---|
Compiled directly into the final binary in the last step of the compilation process | Linked at runtime as a separate file |
Part of the executable | External library |
Highly portable, as no external dependencies are needed at runtime | Less portable, as it depends on system environment and installed libraries |
When any changes (updates, patches, etc.) are applied to the library, the executable has to be recompiled | No need to recompile the executable, as the changes will be reflected automatically upon the library update |
No version conflicts, as the dependency is locked at build time | Updating one dependency can break the dependency chain, resulting in "dependency hell" |
Slower, as the memory is loaded every time the binary is executed | Faster, as shared libraries are loaded into memory only once |
Larger, as libraries are duplicated in each binary | Smaller, as shared libraries are loaded into memory once |
The result of the compilation is a single binary file containing both the original code and the library code | The result is a binary relying on external library files that must be installed on the system at runtime |
How does Spectra Assure detect vulnerabilities in statically linked dependencies?β
Traditional Software Composition Analysis (SCA) tools typically work earlier in the development process by inspecting package managers, manifest files, or source repositories. They rely on known signatures of open-source dependencies and cross-reference them against vulnerability databases. While effective for common cases, SCA tools have limited visibility into deep file structures or tampering that may occur during the build process.
In contrast, Spectra Assure analyzes post-build artifacts. Through layered verification across both direct and transitive dependencies, it can detect not only explicitly malicious components but also those compromised indirectly through infected dependencies. It is also capable of detecting the specific library versions included in a binary and uncovering evidence of build manipulation. This enables the detection of novel or more sophisticated software supply chain attacks that SCA tools may not be able to identify, giving a more accurate picture of risk exposure in statically linked dependencies.
The process of detecting and identifying vulnerabilities depends on how dependencies are linked. With dynamically linked libraries, the runtime environment is a key factor. A library could be updated or replaced independently of your build, so you must verify which versions are actually loaded at runtime in order to assess exposure.
On the other hand, with statically linked libraries, the included version is locked into the binary at build time. This means that once the version is identified, the associated security risk can be assessed directly without additional runtime checks.
In both cases, once a library and its version are identified, assessing vulnerabilities becomes straightforward. Security advisories and CVE records are usually tied to specific versions or version ranges, so knowing the exact version allows you to determine:
- which vulnerabilities apply,
- which patches are missing, and
- whether updates or fixes are required.
Challenges with static dependenciesβ
Sometimes detecting vulnerabilities in statically linked libraries comes with some challenges:
- Hidden identity and version. Once a library is statically linked, its presence is not obvious. Unlike with dynamically linked libraries, you cannot easily see which versions are included in the binary. Any vulnerabilities in these libraries may therefore remain hidden.
- Patched but unbumped versions. Sometimes if a CVE is discovered, a library is patched without updating its version string. In these cases, the "nominal version" of the library may not accurately reflect its security state. Additional sources of information, such as commit hashes or vendor documentation, may be needed.
- Locally modified libraries. Developers may modify a library before it is statically linked. Once altered, its version no longer matches the official release, making vulnerability matching more complex and standard dependency management tools less effective.
Managing static dependenciesβ
To avoid the aforementioned issues, you should focus on managing dependencies used in the applications you develop. Dependency management for static dependencies involves:
- selecting stable versions to build against, ensuring compatibility across different environments or operating systems
- obtaining dependencies from reputable sources, as their code becomes a permanent part of your executable and any malicious or compromised component is embedded directly in your application
- monitoring licenses and compliance, since statically linked code is redistributed within your binary and may introduce legal obligations
- verifying reproducibility and integrity, by pinning exact versions and checking hashes to guard against supply chain tampering
- tracking known vulnerabilities, as outdated static libraries can silently introduce security risks that persist until a new build is released
- establishing a patch workflow, so that critical library updates can be incorporated quickly and new binaries released without delay
Due to the nature of static dependencies, maintaining consistent and automated build processes is necessary for ensuring reliability. To further improve security and efficiency and avoid any silent vulnerabilities, reduce the potential attack surface by removing any unused libraries and leaving only what's required for the best performance of your application.
The case of zlibβ
Precompiled libraries can bring in statically linked dependencies without the developerβs knowledge. A common example is zlib, a widely used C library for data compression that is embedded in operating systems, programming languages, and many applications.
It is frequently compiled directly into software, so it may not always show up in dependency lists and SBOMs. As a result, developers, while building their software, often use some open-source libraries unknowingly containing zlib. When a vulnerability is discovered in zlib, projects that implicitly depend on it may remain unaware and fail to apply critical updates, leaving them exposed.
However, ReversingLabs uses zlib signatures that are precise as they include the library copyright, the exact version, and in some cases even the vulnerable code itself. This allows the analysis engine behind Spectra Assure products to detect the vulnerable code and confirm its near-certain presence within the files listed in the SBOM view of the SAFE report.
One example package that contains a silent zlib vulnerability is the DicomObjects
package.
The ReversingLabs analysis engine discovered that it includes the outdated Dynamic PDF Viewer package, which contains a statically linked zlib file affected by multiple known vulnerabilities.
In this case, the dependency is not even explicitly documented, so thereβs no way to know that DynamicPDF Viewer itself relies on the vulnerable zlib library.
This illustrates a common maintenance issue - developers include third-party software but overlook it during updates. Such hidden, stacked dependencies create multiple layers of silent vulnerabilities, making maintenance, auditing, and vulnerability detection more difficult. While these practices speed up development, they also increase long-term security risk.
What if several zlib versions are statically linked in the same executable?β
It is possible for an executable to contain multiple statically linked versions of zlib.
In one case, a CVE affecting both zlib versions was detected, but the vulnerability was patched in only one of them. Although the overall assessment of the vulnerability impact was accurate, the incomplete remediation created a false sense of security. The issue appeared resolved, but in reality, the second vulnerable version of zlib remained embedded in the executable.
To help you avoid this, use Spectra Assure to reanalyze your software after patching detected vulnerabilities. Check the generated report to see if you missed any hidden or duplicate versions.
How to manually verify the presence of zlib?β
The presence of zlib can be verified manually because, when its source code is statically compiled, it often leaves behind identifiable artifacts in the resulting binary. Among the most recognizable artifacts are copyright strings that typically include the names of the zlib authors:
- inflate 1.2.1 Copyright 1995-2003 Mark Adler
- deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly
These copyright strings are especially valuable because they often contain version numbers, enabling analysts to determine which version of zlib is embedded and to assess which known vulnerabilities it is impacted by. Known zlib vulnerabilities can then be cross-referenced in the CVE Details vulnerability repository.
While manual verification of zlib presence is possible, it requires expertise and can be time-consuming. In cases involving silent vulnerabilities, where no visible artifacts are present, manual detection becomes even more challenging.
Where to find information on dependencies?β
You can find information on dependencies in:
- the CLI
inspect
command output - the Portal interface
- various report types (SAFE, CycloneDX, and SPDX)
CLIβ
When using the CLI, getting information on all components and dependencies is possible with the rl-secure inspect --sbom
command.
For every component and dependency, the output of this command shows the information on licenses, copyrights, and security references.
If any malicious or suspicious components or dependencies are found, the command output points to the file that triggered the detection. This helps you understand the severity of the issue and address it more rapidly by locating the source of the problem.
Dependencies can be excluded with the --no-dep[endencie]s
option.
- Simplified input
- Extended input
- Output
rl-secure inspect --sbom pkg:rl/my-project/my-package@1
rl-secure inspect --show-sbom --purl=pkg:rl/my-project/my-package@1 --rl-store=/home/armando/my-repository/
--------------------------------------------------------------------------------
[ PURL:v1 ] pkg:npm/1Clipboard@0.1.8
[ NVD:CPE ] UNKNOWN
SBOM Entry: COMPONENT
VERIFIED: NO
Product: 1Clipboard
Version: 0.1.8
Publisher: 1Clipboard
Authors: 1Clipboard
License: Permissive (MIT)
Repository: --
Homepage: http://1clipboard.io
References ---------------------------------------------------------------------
1) binary_layer/resource/DATA/131:1033/1Clipboard-0.1.8-full.nupkg/lib/net45/resources/app.asar/package.json
--------------------------------------------------------------------------------
[ PURL:v1 ] UNKNOWN
[ NVD:CPE ] cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*
SBOM Entry: DEPENDENCY
VERIFIED: YES (Byte Pattern)
Product: FFmpeg-libavutil
Version: 2.8-dev
Publisher: FFmpeg Team
Authors: --
License: Weak Copyleft (LGPL-2.1-or-later OR LGPL-3.0-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later)
Repository: --
Homepage: --
References ---------------------------------------------------------------------
1) binary_layer/resource/DATA/131:1033/1Clipboard-0.1.8-full.nupkg/lib/net45/1Clipboard.exe
Portalβ
For all package versions uploaded to the Portal, whether to File Stream or Projects, all SBOM components are listed on the Bill of Materials > Software page of the report. All components and relevant non-SBOM components can be found on the Audit > Components page of the report. This also applies to all reports shared from the Portal.
Reportβ
- SAFE
- CycloneDX
- SPDX
In the SAFE report, the information is organized in the following way:
- Bill of Materials > Software - a comprehensive list of components and dependencies
- Audit > Components - a file explorer, where for each component inside a software package, a list of dependencies is shown
Both pages allow filtering the results based on the type of linking (dynamically or statically linked dependencies, or release or develop package dependencies).
CycloneDX contains only SBOM components and dependencies, along with services, ML models, cryptographic assets, and relationships within a software package. Non-SBOM components are only referenced as a location for services, ML models, or cryptographic assets they include. This report format can be exported from Spectra Assure products as a JSON file.
SPDX contains only SBOM components and dependencies, along with services, ML models, and relationships within a software package. Non-SBOM components are only referenced as a location for services or ML models they include. This report format can be exported from Spectra Assure products as a JSON file. As opposed to CycloneDX, this report format does not reference cryptographic assets.