Security Tools

Security Tools: Automating Defense

Security shouldn’t be an afterthought. In Go, we have tools to detect vulnerabilities statically.

Security Pipeline (Suggested)

commit --> static checks --> vuln scan --> crypto tests --> release
            |                 |              |
            +-- gosec         +-- govulncheck +-- testing/cryptotest
            +-- nilaway

1. govulncheck: Reachability-Based Vulnerability Scanner

Use govulncheck first because it reports vulnerabilities your code can actually reach.

go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

2. gosec: The Security Linter

gosec scans your AST for bad patterns.

gosec ./...

Common things it catches: * Hardcoded credentials/tokens. * SQL injection risks (string concatenation in queries). * Weak random number generation (math/rand vs crypto/rand). * Permissions (e.g., 0777 on files).

3. capslock: Capability Analysis

Google’s capslock is a fascinating tool. It tells you what capabilities a package uses.

Does that innocent looking leftpad library also import net/http and send your ENV vars to a server? capslock will tell you.

capslock -packages ./...

It outputs capability classes such as Network, FileSystem, Reflection. If a simple helper package needs Network, treat it as suspicious.

4. nilaway: Compile-time Nil Panics

Uber’s nilaway is a static analyzer that detects potential nil pointer dereferences. It is more powerful than standard linters because it traces flows across functions. It effectively brings a degree of “Option Type” safety to Go pointers.

5. Go 1.26 Crypto Additions

crypto/hpke

Go 1.26 adds HPKE (Hybrid Public Key Encryption) in the standard library, useful for modern envelope encryption and E2E protocols.

testing/cryptotest

Go 1.26 adds testing/cryptotest to validate cryptographic implementations against correctness properties.

6. Experimental: runtime/secret

runtime/secret is an experiment in Go 1.26 for handling sensitive values with tighter lifetime controls.

//go:build goexperiment.runtimesecret

import "runtime/secret"

func useSecret() {
    token := []byte("api-token")
    secret.Do(func() {
        // work with token inside protected lifetime window
        _ = token
    })
}

Use experiments deliberately:

GOEXPERIMENT=runtimesecret go test ./...