Security Post-it #7 – Software Security Testing for Golang

In this short security post-it, I explain how to secure your Golang code using open-source tools: SAST and SCA.

Nov 22, 2022 by Nicolas Béguier

We all agree that you have to secure your code. On the other hand, it is not always easy to know where to start and identify what is effective. I will present here the SAST and SCA implementations on your Golang repositories.

Oh wait, I forgot to tell you. This is to build it yourself on your CI/CD or in your pre-commit hooks, with open-source tools.

Check out my other article to protect your Javascript and Typescript repositiories.

What are SAST and SCA ?

Static Application Security Testing (SAST) is used to scan the code you write for security vulnerabilities and Software Composition Analysis (SCA) is used to scan your dependencies for security vulnerabilities.

When we look at these two technologies side by side, it becomes clear that both are necessary for an effective and secure development approach. SAST is more helpful for the code you write, while SCA is effective at analyzing the open-source software your organization uses, as well as its dependencies. These two technologies address security issues early and often during the development cycle.

In my opinion, SAST should be both asynchronous and synchronous. Blocking CI/CD pipelines to prevent unsecured code is great, but you need to specify exceptions and false-positive management. Running it asynchronously permits your security team to read reports and be alerted in real-time for potential vulnerabilities.
SCA must be asynchronous only, otherwise you will only be alerted when new code is pushed. Dead repositories are full of vulnerable dependencies. Run it somewhere else but continuously, and why not use a tool to create Pull Requests automatically, like Renovabot.

Static Application Security Testing (SAST)

Today, the best SAST tool to audit your Golang repository is gosec.

Install

$ go install github.com/securego/gosec/v2/cmd/gosec@latest # For a temporary install
$ curl -L https://github.com/securego/gosec/releases/download/v2.14.0/gosec_2.14.0_linux_amd64.tar.gz -o /tmp/gosec.tar.gz && tar xvzf /tmp/gosec.tar.gz -C /tmp/ -x gosec # /tmp/gosec

Audit

Human readable output $ gosec -exclude=G301,G302,G303,G304,G305,G306,G307,G401,G402,G403,G404,G501,G502,G503,G504,G505,G601 -severity medium -confidence medium -exclude-dir vendor/ __CODE_DIRECTORY__/...
Work with a JSON output $ gosec -exclude=G301,G302,G303,G304,G305,G306,G307,G401,G402,G403,G404,G501,G502,G503,G504,G505,G601 -severity medium -confidence medium -exclude-dir vendor/ -fmt json -out /tmp/gosec.json __CODE_DIRECTORY__/... $ cat /tmp/gosec.json | jq .Issues

Example

Let's take as an example this random Golang repository, still maintain. # Clone the repo in /tmp.
$ git clone https://github.com/newrelic/go-agent /tmp/go-agent
# Scan it with gosec.
$ gosec -exclude=G301,G302,G303,G304,G305,G306,G307,G401,G402,G403,G404,G501,G502,G503,G504,G505,G601 -severity medium -confidence medium -exclude-dir vendor/ /tmp/go-agent/...

[/tmp/go-agent/internal/serverless.go:203] - G110 (CWE-409): Potential DoS vulnerability via decompression bomb (Confidence: MEDIUM, Severity: MEDIUM)
202: var out bytes.Buffer
> 203: io.Copy(&out, gz)
204: gz.Close()

Summary:
Gosec : 2.14.0
Files : 364
Lines : 54408
Nosec : 0
Issues : 14

Does it work on my CI ?

https://github.com/securego/gosec#github-action

There is documentation for:
  • GitHub Actions

Software Composition Analysis (SCA)

govulncheck reports known vulnerabilities that affect Go code. It uses static analysis of source code or a binary's symbol table to narrow down reports to only those that could affect the application.

However, you need the precence of the go.mod file and support badly errors. If you are blocked, you should use nancy, sometimes less accurate but it's doing a great job.

Install

$ go install golang.org/x/vuln/cmd/govulncheck@latest # or try nancy
$ curl -L https://github.com/sonatype-nexus-community/nancy/releases/download/v1.0.42/nancy-v1.0.42-linux-amd64.tar.gz -o /tmp/nancy.tar.gz && tar xvzf /tmp/nancy.tar.gz -C /tmp/ -x nancy # /tmp/nancy

Audit

Human readable output $ cd __CODE_DIRECTORY__ $ govulncheck ./...
Work with a JSON output $ govulncheck -json ./... > /tmp/gosec.json
... or you can try Nancy $ cd __CODE_DIRECTORY__ $ go list -e -json -deps ./... 2>/dev/null | nancy sleuth

Example

Let's take as an example this random Golang repository. # Clone the vulnerable repo in /tmp.
$ git clone https://github.com/netlify/gotell.git /tmp/gotell
$ cd /tmp/gotell $ govulncheck ./...

Vulnerability #19: GO-2020-0012
An attacker can craft an ssh-ed25519 or sk-ssh-ed25519@openssh.com public key, such that the library will panic when trying to verify a signature with it. If verifying signatures using user supplied public keys, this may be used as a denial of service vector.
Found in: golang.org/x/crypto/ssh@v0.0.0-20160915071417-81372b2fc2f1
Fixed in: golang.org/x/crypto/ssh@v0.0.0-20200220183623-bac4c82f6975
More info: https://pkg.go.dev/vuln/GO-2020-0012

Does it work on my CI ?

https://github.com/sonatype-nexus-community/nancy

There is no documentation for govulncheck, but for Nancy:
  • GitHub Actions
  • Circle CI

Conclusion

You don’t necessarily need an expensive code scanner like Snyk or CherckMarx, you can build it yourself. If you put it in pre-commit hooks, CI/CD and asynchronous you will have a complete view of your application security risk and earn awareness of the developers about security concerns.
At Tandem Technology, we'll help you improve your development practices during a workshop to harden your code repository.

If you enjoyed this story, please recommend and share to help others find it! Feel free to contact me if you have any questions.