Security vulnerabilities exist in any language and any code, some are written by ourselves, but more are from the upstream dependencies, even the underlying Linux. We have discussed the security protection methods for Go and Kubernetes Image in Path to a Perfect Go Dockerfile and Image Vulnerability Scanning for Optimal Kubernetes Security, in which the security scanning was performed based on generic.
As the Go community grows, more and more open-source packages have caused more security vulnerabilities, which has raised the concern of Go officials, and then the security scanning tool Go Vulnerability Check was introduced in September 2022.
If you are interested in this tool, just follow me, and let’s digest its internal logic and then make full use of it.
Use Go Vulnerability Check
First, let’s try it.
Install(only supported from Go 1.18).
go install golang.org/x/vuln/cmd/govulncheck@latest
Then run it in the project directory, the directory where the go.mod file is located.
govulncheck ./...
Take one of my Kubernetes Operator projects as a demo. Two vulnerabilities are displayed in the report.
- Scanning for dependencies with known vulnerabilities, is the vulnerability in the project code, maybe a vulnerability in the current Go version, and can be solved by upgrading Go.
- The vulnerabilities below are in packages that you import, is the vulnerability in project dependencies, and can only be fixed by upgrading the corresponding package dependencies.
The following is given in both of the vulnerability information.
- How many vulnerabilities are detected
- Specific information about each vulnerability, including submission date, detailed description, and the link to vulnerability reports
- The specific code where the vulnerability is found, such as which method and which line
- The version in which the vulnerability is found and the fixed version
Run Govulnerablity in CI/CD
It is more effective if we integrate the tool into the CI/CD pipeline, which can be implemented by exporting the result of the JSON file and then using -json flag.
govulncheck -json ./...
The JSON file is the verbose output including the scan process, call entries, and scan results.
Calls is the check related to the native code. Imports is the check for dependencies. And Vulns is the check results.
For jq '.Vulns | length'
, we can set != 0. And for the current operator, we can put the relevant bash into the Makefile and run it in CI/CD.
vuln also supports testing of binary files by replacing ./… with the binary file name. Besides, when integrating into CI/CD, it is also suitable for detecting vulnerabilities in Go projects that only have Docker images.
Check Test Code
vuln does not check the test code by default, but you can scan test files with
-test flag govulncheck -test pkg/test/*
Inside Go Vulnerability Check
The vuln tool works by running the command line tool and reading the vuln database to analyze the go.mod file and Go code. So it is mainly composed of two parts.
- Development of the vuln command-line tool
- Maintenance of the vulndb database
Vuln Command-line Tool
Reading the command-line tool code usually starts from where the command line is defined. The whole process is simple, and only 5 steps to check the source.
- Read and configure database client
- Load config
- Read the source code and sequence
- Detect
- Process the results
The core is the vulncheck.source() method.
Build the import and require graphs separately, and perform scanning. import is for what is used in the current code, while require connecting with the dependent packages that are not directly used.
Vuln Database
vulndb contains all vulnerability information, synchronizes some other open-source vulnerability libraries, and introduces vulnerabilities discovered by the community with the tickets submitted by the users. And you can check all relevant vulnerabilities at https://pkg.go.dev/vuln/.
There are six attributes detailing each vulnerability.
Curated dataset. The database will be actively maintained by the Go Security team, and will provide consistent metadata and uniform analysis of the tracked vulnerabilities, with a focus on enabling not just detection, but also precise impact assessment.
Basic metadata. Entries will include a database-specific unique identifier for the vulnerability, affected package and version ranges, a coarse severity grade, and GOOS/GOARCH if applicable. If missing, we will also assign a CVE number.
Targeting metadata. Each database entry will include metadata sufficient to enable detection of impacted downstream applications with low false positives. For example, it will include affected symbols (functions, methods, types, variables…) so that unaffected consumers can be identified with static analysis.
Web pages. Each vulnerability will link to a web page with the description of the vulnerability, remediation instructions, and additional links.
Source of truth. The database will be maintained as a public git repository, similar to other Go repositories. The database entries will be available via a stable protocol (see “The protocol”). The contents of the repository itself will be in an internal format which can change without notice.
Triage process. Candidate entries will be sourced from existing streams (such as the CVE database, and security mailing lists) as well as community submissions. Both will be processed by the team to ensure consistent metadata and analysis. We want to specifically encourage maintainers to report vulnerabilities in their own modules.
When implementing, vulndb also provides a set of cmd commands for database maintenance, online verification, etc. For example, the worker command can start a server locally and scan the files in Git.
The cve command can query and update vulnerability information, calling HTTP requests to get relevant information.
We can download the vulndb code git clone https://github.com/golang/vulndb.git, and then test and run these commands locally via the script under devtools.
Alternatives
The vuln is from Go official and is supposed to be popular soon, but there are still some drawbacks.
- It is only aExpeirmental tool.
- It only supports binary code checks from Go 1.18 and above.
- It only detects vulnerabilities in the current Go version. For example, if I upgrade my Go to the latest 1.19, then the dependencies’ vulnerabilities in 1.18 will not be reported.
- Its output method is limited. JSON output is too complicated, and text is only for the local environment, such as the summary output format in the source code only supports the development and testing environment.
- It returns false positive or inaccurate stack reports when scanning interfaces and function pointers.
Don’t stick there, and look at other Go dependency security scanning tools when waiting vuln tool to be perfected. The most prevailing ones currently are the Github security dependency scan and the gosec tool.
GitHub Security Dependency Scan
For open-source Github Go projects, we can perform regular dependency scans by configuring Dependabot alerts in settings.
The GitHub security scan supports daily or weekly scan reports by email or GitHub notifications. And it also provides shortcuts for one-click fixes, ideal for open-source Go projects.
gosec Tool
The gosec tool is very similar to the vuln tool, both are command-line tools and scan Go vulnerabilities with similar rules.
But gosec supports all Go versions and is richer in operation options, such as scanning specific rules, scanning configuration files, and output reports in multi formats like JSON, YAML, CSV.
It can be said that gosec is more mature before more functions are provided in vuln.
Conclusion
As Go develops and more and more security issues occur, it is very important to carefully select the dependencies and update them on a regular basis. However, it is not an easy task when regular updates of pr and merge are required. which will be ignored by some users. Dependency scanning is the way out, forcing the users to update by failing the build in CI/CD directly.
The vuln tool is under evolution, and I will follow closely on it and look forward to its future optimization.
Reference
- https://go.dev/blog/vuln
- https://go.googlesource.com/proposal/+/master/design/draft-vulndb.md
- https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository
- https://github.com/securego/gosec
Note: The post is authorized by original author to republish on our site. Original author is Stefanie Lai who is currently a Spotify engineer and lives in Stockholm, original post is published here.