November 10 marks the 13th anniversary of the first release of Golang. To celebrate the occasion, we invited our colleague Rostislav Bagrov, Senior Machine Learning Engineer in the News UK Tech team at Questers, to share his observations on one of the newest tools introduced in the language – “govulncheck”. Check out what he shared:
Golang is a programming language that has been constantly developing, maturing and introducing new features and tools. One new initiative or experiment is the relatively new tool for vulnerability checks „govulncheck" introduced on September 6 this year. This new tool provides analysis and surfaces known vulnerabilities in your codebase.
So, let’s outline a few practical bits about it.
Firstly, this tool is entirely CLI (Command Line Interface) and can scan packages (source files) or binaries (compiled files) for vulnerabilities. It can explicitly scan tests as well.
Another thing about the “govulncheck” is that the output contains structured information of what is found as a print on the screen. It allows the option for programmatic use by outputting a JSON structure of the discovered vulnerabilities. However, it cannot directly write this to a file. If you want it in a file, you need to manually redirect it.
Here is how a non-JSON output looks like:
Vulnerability #11: GO-2022-0969
HTTP/2 server connections can hang forever waiting for a clean
shutdown that was preempted by a fatal error. This condition can
be exploited by a malicious client to cause a denial of service.
Found in: net/[email protected]
Fixed in: net/[email protected]
More info: https://pkg.go.dev/vuln/GO-2022-0969
And here is its equivalent in JSON:
The JSON output is preferable as it brings much more addressable information. Third-party integration is also possible using this method. It is safe to transfer to analysis systems because it doesn't contain any local paths or references even in verbose mode.
Another important thing to mention is that “govulncheck” supports build tags as well. This allows building different versions of a Go application from the same source code. Essentially, this saves a lot of time as you can run vulnerability checks on just a specific tag if your project requires this.
If we take a look at the tool's internal architecture, we’ll see that it is not entirely SL (standard library) and it uses few external packages to formulate the codebase. It uses an external vulnerability database maintained by Google folks. Standard interchange format is introduced for the vulnerability records and the database utilises the so-called open-source vulnerability schema - OSV. This makes it compatible with other similar databases and compliant with latest standards for the topic. It basically can read other databases (OSV/nonOSV) and construct / transform vulnerability records by OSV standard.
Internally, as expected, the database client is detached from the main codebase and new database clients / implementations have to match the established interface.
When initiated, the tool attempts to build the import chain from the code and based on that to fetch from the database the relevant analysis. With this it narrows the scope to ease the query to the database and provide exact recommendations for the particular case. The code performs detection of vulnerable symbols.
Essentially, you can use this tool in pre-commit mode with a hook and after compile for sanity checks.
Personally, I find it very useful as it helps shipping more secure code to end users. The early adopters of the idea would have automated vulnerability checks using native to the ecosystem component. This will result in improving predictability of the final product.
I can only speculate about the future of the “govulncheck” tool, however, its structure enables contributors to add and use different sources of information and perform multiple very precise checks (using tags and specific platform builds). And even though it is currently called an experiment, most mature languages contain such a service/tool and it is unlikely that this idea will disappear from the Golang ecosystem. It is more likely that we are witnessing the beginning of a new era for the language stepping up into the world of older more mature programming languages.