binpkg

package
v3.83.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package binpkg discovers packages from compiled artefacts — the case where a dependency exists in a container image or release archive but no manifest, lockfile or package database mentions it.

Three evidence sources are read, all offline and metadata-only:

  • Go build info embedded by the toolchain (ELF, PE, Mach-O and XCOFF): the main module, every dependency module with its go.sum H1 hash, and the toolchain itself (reported as the `stdlib` package in the Go ecosystem, which is how Go toolchain advisories are indexed).
  • Rust `cargo auditable` data (the zlib-compressed JSON in the ELF `.dep-v0` section), including its crate-level dependency edges.
  • JVM archives: Maven coordinates from `META-INF/maven/**/pom.properties`, `MANIFEST.MF` attributes, or the archive filename, including jars nested one level deep inside a fat/Spring-Boot jar.

Nothing here executes the artefact or reads a byte of its payload beyond the metadata sections named above.

Index

Constants

View Source
const (
	MethodGoBuildInfo    = "go-buildinfo"
	MethodCargoAuditable = "cargo-auditable"
	MethodJVMArchive     = "jvm-archive"
	MethodOSFileOwner    = "os-file-owner"
)

Discovery methods, written verbatim into Package.Method and surfaced as CycloneDX evidence on the component.

View Source
const (
	ScopeProduction  = "production"
	ScopeDevelopment = "development"
)

Scope values mirror internal/scan's scope vocabulary without importing it — binpkg is deliberately dependency-free so it can be reused by the analyze and container paths.

Variables

This section is empty.

Functions

func HasFileOwnership

func HasFileOwnership(root string) bool

HasFileOwnership reports whether the root filesystem carries any package database whose file lists this package can read. It is false for rpm-only images and for arbitrary directories, which is the signal callers need before concluding a binary belongs to no package.

func LooksExecutable

func LooksExecutable(path string) bool

LooksExecutable reports whether a file is worth handing to FromBinary: an ELF, PE, Mach-O or XCOFF magic number, or a JVM archive extension. Callers use it to avoid reading every file in a container filesystem twice.

func RelativePath

func RelativePath(root, path string) string

RelativePath renders a path inside the scanned tree for use as a CycloneDX locator: slash-separated and relative to root when possible.

Types

type Artifact

type Artifact struct {
	Path       string
	Format     string
	Owner      *Owner
	Attributes map[string]string
	Packages   []Package
}

Artifact is one compiled file that yielded package metadata or an ownership attribution.

type Edge

type Edge struct {
	From      string
	DependsOn []string
}

Edge is a dependency relation between two discovered packages, expressed with the same "name@version" keys the caller uses to build bom-refs.

type Owner

type Owner struct {
	Name      string
	Version   string
	Ecosystem string // deb, apk or arch
	// Source is the package-database file the attribution came from, relative to
	// the container root.
	Source string
}

Owner identifies the OS package that installed a file inside a container root filesystem.

func (Owner) Key

func (o Owner) Key() string

Key is the "name@version" identity used to line the owner up with the package component parsed out of the same package database.

type OwnerIndex

type OwnerIndex map[string]Owner

OwnerIndex maps an absolute in-container path ("/usr/bin/curl") to the package that installed it. Paths are stored slash-separated and rooted, exactly as the package databases record them.

func BuildOwnerIndex

func BuildOwnerIndex(root string) OwnerIndex

BuildOwnerIndex reads the file lists of every package database present under a container root filesystem: dpkg (`var/lib/dpkg/info/*.list`), apk (`lib/apk/db/installed` F:/R: records) and pacman (`var/lib/pacman/local/*/files`).

RPM is intentionally absent: its database is a Berkeley DB or SQLite file that cannot be read without linking a native library, so rpm-based images get package components (from the `sca` container pass) without per-file attribution. Callers should not treat a missing owner as "unpackaged" for those images — see HasFileOwnership.

func (OwnerIndex) Lookup

func (idx OwnerIndex) Lookup(root, hostPath string) (Owner, bool)

Lookup resolves a path on the host (inside the extracted root) back to its owning package. root is the container root filesystem directory.

type Package

type Package struct {
	Name      string
	Version   string
	Ecosystem string
	Scope     string
	IsDirect  bool
	Method    string
	Detail    string
	// Confidence is how strongly the evidence identifies the package: "high" for
	// what the build tool itself recorded, "medium" for archive metadata a human
	// can set freely, "low" for a name/version read off a filename.
	Confidence string
	Checksum   string // go.sum-style H1 hash when the source provides one
	BinaryPath string
}

Package is one dependency recovered from a compiled artefact.

func Dedupe

func Dedupe(pkgs []Package) []Package

Dedupe collapses packages that were discovered more than once (the same module linked into several binaries), keeping the first occurrence's provenance and merging nothing but direct-ness, and returns them in a stable order.

type Result

type Result struct {
	// Format identifies what was recognised: "go", "rust", "jvm" or "" when the
	// artefact carries no package metadata at all.
	Format   string
	Packages []Package
	Edges    []Edge
	// Attributes are extra facts about the artefact itself (VCS revision, build
	// settings, toolchain) that belong on the binary component, not on a package.
	Attributes map[string]string
	// Errors records metadata that was present but unreadable. A file with no
	// metadata at all is not an error.
	Errors []string
}

Result is everything one artefact yielded.

func FromArtifact

func FromArtifact(path string) Result

FromArtifact dispatches on file shape: JVM archives by extension, everything else through the compiled-binary readers. It never returns an error — an unreadable or uninteresting file yields an empty Result, because callers walk whole container filesystems where most files are neither.

func FromBinary

func FromBinary(path string) Result

FromBinary reads package metadata embedded in a compiled binary.

func FromJVMArchive

func FromJVMArchive(path string) Result

FromJVMArchive recovers Maven coordinates from a jar/war/ear. The three evidence sources, in descending confidence:

  1. META-INF/maven/<group>/<artifact>/pom.properties — written by Maven itself
  2. META-INF/MANIFEST.MF Implementation-* / Bundle-SymbolicName attributes
  3. the archive filename ("commons-lang3-3.14.0.jar")

Fat jars are unpacked one level: every jar under BOOT-INF/lib, WEB-INF/lib or lib/ is inspected the same way, which is where a Spring Boot application's real dependency set lives.

func (Result) Empty

func (r Result) Empty() bool

Empty reports whether the artefact produced nothing worth recording.

type TreeOptions

type TreeOptions struct {
	Root string
	// SkipDirs are additional directory base names to prune.
	SkipDirs []string
	// MaxFileSize overrides defaultMaxFileSize when positive.
	MaxFileSize int64
	// Owners attributes each artefact to the OS package that installed it. Build
	// it with BuildOwnerIndex for a container root filesystem; leave nil
	// otherwise.
	Owners OwnerIndex
}

TreeOptions configures ScanTree.

type TreeResult

type TreeResult struct {
	Artifacts []Artifact
	Packages  []Package
	Edges     []Edge
	// Examined counts files that looked like a compiled artefact and were parsed.
	Examined int
	// Unowned counts artefacts that no package database claims. It is only
	// meaningful when Owners was supplied — an unclaimed binary in an image with a
	// package database is a file that arrived outside the package manager.
	Unowned []string
	Errors  []string
}

TreeResult aggregates a whole-tree scan.

func ScanTree

func ScanTree(opts TreeOptions) TreeResult

ScanTree walks a directory tree and extracts embedded package metadata from every compiled artefact it finds. It is offline and read-only, and never returns an error for the tree as a whole: unreadable files are recorded in Errors so one bad file cannot abort an SBOM.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL