Checking code for security vulnerabilities
Introduction
To ensure the security of the codebase, it is essential to check for vulnerabilities in the dependencies used by the project.
This can be done using various tools such as grype that scan the container images, filesystems, and SBOMs (Software Bill of Materials) for known vulnerabilities.
The installation and usage of grype can be found in the Grype documentation
Running grype on the project
To run grype on the project, you can use the following command in the terminal:
grype DIRECTORY-TO-SCAN
For example, if using a pixi environment, you can run:
grype ./.pixi/envs/{env_name}/
This command will scan the specified directory for vulnerabilities in the dependencies and provide a report of the issues found, including the severity and recommended actions to mitigate them.
Whilst, the above command will print the report in the terminal, you can also export the report to a file using the -o flag followed by the desired output format (e.g., json) and the output file name. For example:
grype DIRECTORY-TO-SCAN -o json > grype_report.json
Interpreting the grype report
The grype report will list the vulnerabilities found in the scanned directory, along with details such as the package name, version, vulnerability ID, severity level, and a description of the issue.
The report will also provide recommendations for mitigating the vulnerabilities, such as updating to a newer version of the affected package or applying patches.
Vulnerability ID
The vulnerability ID is a unique identifier assigned to each issue, which can be used to look up more information about the vulnerability and its potential impact. Each vulnerability may have a different ID format depending on the source of the vulnerability information. For example, vulnerabilities from the National Vulnerability Database (NVD) are typically identified by a CVE (Common Vulnerabilities and Exposures) ID, while vulnerabilities from GitHub may be identified by a GHSA (GitHub Security Advisory) ID. More information regarding CVE vulnerabilities can be found in the CVE documentation.
To understand the impact of a particular vulnerability, the ID can be looked up in the relevant database (e.g., NVD or GitHub) to find details on severity, affected versions, and recommended mitigations. For example, if a vulnerability is identified with the ID CVE-2026-6100, you can search for this ID in the NVD to find more information about the vulnerability and how to address it.
Prioritizing vulnerabilities
When reviewing the grype report, it is important to prioritize the mitigation of vulnerabilities based on their severity level and potential impact on the project.
Recommendations for mitigating the vulnerabilities may not always be straightforward. Some packages may not have a newer version available that addresses the vulnerability, or updating to a newer version may introduce compatibility issues with other dependencies in the project.
In such cases, it is important to carefully evaluate the risks and benefits of each mitigation strategy and choose the one that best fits the project's needs and constraints.
Checking for transitive dependencies and relevance of vulnerabilities
Sometimes, vulnerabilities that are reported may not arise from a direct dependency of the project but from a transitive dependency (i.e., a dependency of a dependency). In such cases, it is important to investigate the issue further to determine if it can be safely ignored or if it requires action to be taken. To investigate the issue, you can check the dependency tree of the project to identify which package is causing the vulnerability and whether it is a direct or transitive dependency. Inside a pixi environment, you can use the following command to check the dependency tree:
pixi tree PACKAGE-NAME
Additionally, you can also check the grype.json report and check the location field to identify the path of the vulnerable package and determine if it is a direct or transitive dependency.
If it is a direct dependency, the vulnerability should be addressed by updating the package or applying patches. If it is a transitive dependency, you can check if there is a newer version of the direct dependency that includes a fix for the vulnerability in the transitive dependency. If not, you may need to consider alternative mitigation strategies, such as using a different package that does not have the vulnerability or applying patches to the transitive dependency directly.
Reviewing if security patches have already been applied
Certain vulnerabilities may have already been addressed by security patches that have been applied to the packages. These can be verified by checking the package's release notes or changelog for any mentions of security fixes.
To summarize, the following steps can be taken to check for security vulnerabilities in the codebase:
- Use
grypeto scan the project for vulnerabilities in the dependencies. - Review the
grypereport to identify the vulnerabilities found, their severity levels, and recommended mitigations. - Resolve the vulnerabilities by updating to newer versions of the affected packages, applying patches, or considering alternative mitigation strategies.
- If a vulnerability is found in a transitive dependency, investigate the issue further to determine if it can be safely ignored or if it requires action to be taken.
- Check for any security patches that may have already been applied to the packages to ensure that the vulnerabilities have been addressed.
- If none of the above steps can be taken to mitigate the vulnerabilities, carefully evaluate if the vulnerable package can be safely ignored based on the context of its usage in the project. Document the rationale for ignoring the vulnerability and monitor for any updates or patches that may address the issue in the future.
Comparing Vulnerability reports over time / branches
To track the security of the codebase over time, it can be helpful to compare vulnerability reports across different branches or time periods. This can be done by generating grype reports for each branch or time period and comparing the results to identify any new vulnerabilities that may have been introduced or any existing vulnerabilities that have been resolved.
To compare the reports sarif-tools can be used to identify the differences between two grype reports in sarif format. The following command can be used to compare two reports:
git checkout feature-branch1 grype ... -o sarif --file vuln-branch1.sarif git checkout feature-branch2 grype ... -o sarif --file vuln-branch2.sarif
pixi exec --with sarif-tools sarif diff -o sarif-diff.json vuln-branch1.sarif vuln-branch2.sarif
