Go

Go package analysis and vulnerability scanning capabilities

Package analysis

Cataloger + Evidence License Dependencies Package Manager Claims
Depth Edges Kinds Files Digests Integrity Hash
go-module-binary-cataloger
application/x-executable, application/x-mach-binary, application/x-elf, application/x-sharedlib, application/vnd.microsoft.portable-executable, application/x-executable (mimetype)
transitive flat runtime, dev
go-module-file-cataloger
go.mod
transitive flat runtime, dev
Syft Configuration
Configuration Key Description
golang.local-mod-cache-dir Specifies the location of the local go module cache directory. When not set, syft will attempt to discover the GOPATH env or default to $HOME/go.
golang.local-vendor-dir Specifies the location of the local vendor directory. When not set, syft will search for a vendor directory relative to the go.mod file.
golang.no-proxy Is a list of glob patterns that match go module names that should not be fetched from the go proxy. When not set, syft will use the GOPRIVATE and GONOPROXY env vars.
golang.proxy Is a list of go module proxies to use when fetching go module metadata and licenses. When not set, syft will use the GOPROXY env or default to https://proxy.golang.org,direct.
golang.search-local-mod-cache-licenses Enables searching for go package licenses in the local GOPATH mod cache.
golang.search-local-vendor-licenses Enables searching for go package licenses in the local vendor directory relative to the go.mod file.
golang.search-remote-licenses Enables downloading go package licenses from the upstream go proxy (typically proxy.golang.org).

Version detection for binaries

When Syft scans a Go binary, the main module often has version (devel) because Go doesn’t embed version information by default. Syft attempts to detect the actual version using three strategies (configurable via golang.main-module-version.*):

  1. From ldflags (enabled by default): Looks for version strings passed during build like -ldflags="-X main.version=v1.2.3". Supports common patterns: *.version=, *.gitTag=, *.release=, etc.

  2. From build settings (enabled by default): Uses VCS metadata (commit hash and timestamp) embedded by Go 1.18+ to generate a pseudo-version like v0.0.0-20230101120000-abcdef123456.

  3. From contents (disabled by default): Scans binary contents for version string patterns. Can produce false positives.

Best practice: Use -ldflags when building to embed your version explicitly.

Example:

go build -ldflags="-X main.version=v1.2.3"

This ensures Syft (and Grype) can accurately identify your application version for vulnerability matching.

Standard library

Syft automatically creates a stdlib package for each Go binary, representing the Go standard library version used to compile it. The version is extracted from the binary’s build metadata (e.g., go1.22.2). This enables Grype to check for vulnerabilities reported against the go standard library.

Why this matters: Vulnerabilities in the Go compiler (like CVEs affecting the crypto library or net/http) can affect your application even if your code doesn’t directly use those packages.

Vulnerability scanning

Data Source Disclosures Fixes Track by
Source
Package
Affected Date Versions Date
GitHub Security Advisories (GHSA)
National Vulnerability Database (NVD)
Grype Configuration
Configuration Key Description
match.golang.using-cpes Use CPE package identifiers to find vulnerabilities
match.golang.always-use-cpe-for-stdlib use CPE matching to find vulnerabilities for the Go standard library
match.golang.allow-main-module-pseudo-version-comparison allow comparison between main module pseudo-versions (e.g. v0.0.0-20240413-2b432cf643...)

Main module filtering

Grype skips vulnerability matching for packages that match all these conditions:

  • Package name equals the main module name (from the SBOM metadata)
  • Package version is unreliable:
    • When allow-main-module-pseudo-version-comparison is false (default): version starts with v0.0.0- or is (devel)
    • When allow-main-module-pseudo-version-comparison is true: version is (devel) only

This filtering exists because Go doesn’t have a standard way to embed the main module’s version into compiled binaries (see golang/go#50603). Pseudo-versions in compiled binaries are often unreliable for vulnerability matching.

You can disable this filtering with the allow-main-module-pseudo-version-comparison configuration option.

Troubleshooting

No vulnerabilities found for main module

Cause: The main module has a pseudo-version (v0.0.0-*) or (devel), which Grype filters by default.

Solution: Enable pseudo-version matching in your Grype configuration:

match:
  golang:
    allow-main-module-pseudo-version-comparison: true

No vulnerabilities found for stdlib

Possible causes:

  • Missing CPEs: Verify Syft generates CPEs with generate-cpes: true in .syft.yaml
  • CPE matching disabled: Ensure always-use-cpe-for-stdlib: true in Grype config (default)
  • Incorrect version format: Stdlib version should be go1.18.3, not v1.18.3 (file a Syft bug if incorrect)

Next steps

Last modified October 23, 2025: fix section ref (9417a27)