scan

package
v1.37.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2026 License: AGPL-3.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ScopeProduction  = "production"
	ScopeDevelopment = "development"
	ScopeTest        = "test"
	ScopePeer        = "peer"
	ScopeOptional    = "optional"
	ScopeProvided    = "provided"
	ScopeRuntime     = "runtime"
	ScopeSystem      = "system"
)

Scope constants use native package manager terminology.

Variables

View Source
var ManifestExtensions = map[string]ManifestInfo{
	".csproj":        {Type: "*.csproj", Ecosystem: "nuget", Language: "c#", IsLock: false},
	".tf":            {Type: "*.tf", Ecosystem: "terraform", Language: "hcl", IsLock: false},
	".opam":          {Type: "*.opam", Ecosystem: "opam", Language: "ocaml", IsLock: false},
	".cabal":         {Type: "*.cabal", Ecosystem: "cabal", Language: "haskell", IsLock: false},
	".dockerfile":    {Type: "Dockerfile", Ecosystem: "docker", Language: "docker", IsLock: false},
	".containerfile": {Type: "Dockerfile", Ecosystem: "docker", Language: "docker", IsLock: false},
}

ManifestExtensions maps file extensions to manifest metadata. Used for files whose names include a project-specific prefix (e.g. foo.csproj, main.tf).

View Source
var ManifestFiles = map[string]ManifestInfo{

	"package-lock.json": {Type: "package-lock.json", Ecosystem: "npm", Language: "javascript", IsLock: true},
	"package.json":      {Type: "package.json", Ecosystem: "npm", Language: "javascript", IsLock: false},
	"yarn.lock":         {Type: "yarn.lock", Ecosystem: "npm", Language: "javascript", IsLock: true},
	"pnpm-lock.yaml":    {Type: "pnpm-lock.yaml", Ecosystem: "npm", Language: "javascript", IsLock: true},

	"pyproject.toml":   {Type: "pyproject.toml", Ecosystem: "pypi", Language: "python", IsLock: false},
	"requirements.txt": {Type: "requirements.txt", Ecosystem: "pypi", Language: "python", IsLock: false},
	"requirements.in":  {Type: "requirements.in", Ecosystem: "pypi", Language: "python", IsLock: false},
	"Pipfile":          {Type: "Pipfile", Ecosystem: "pypi", Language: "python", IsLock: false},
	"Pipfile.lock":     {Type: "Pipfile.lock", Ecosystem: "pypi", Language: "python", IsLock: true},
	"poetry.lock":      {Type: "poetry.lock", Ecosystem: "pypi", Language: "python", IsLock: true},
	"uv.lock":          {Type: "uv.lock", Ecosystem: "pypi", Language: "python", IsLock: true},

	"go.sum": {Type: "go.sum", Ecosystem: "golang", Language: "go", IsLock: true},
	"go.mod": {Type: "go.mod", Ecosystem: "golang", Language: "go", IsLock: false},

	"Gemfile":      {Type: "Gemfile", Ecosystem: "rubygems", Language: "ruby", IsLock: false},
	"Gemfile.lock": {Type: "Gemfile.lock", Ecosystem: "rubygems", Language: "ruby", IsLock: true},

	"Cargo.toml": {Type: "Cargo.toml", Ecosystem: "cargo", Language: "rust", IsLock: false},
	"Cargo.lock": {Type: "Cargo.lock", Ecosystem: "cargo", Language: "rust", IsLock: true},

	"pom.xml":         {Type: "pom.xml", Ecosystem: "maven", Language: "java", IsLock: false},
	"build.gradle":    {Type: "build.gradle", Ecosystem: "maven", Language: "java", IsLock: false},
	"gradle.lockfile": {Type: "gradle.lockfile", Ecosystem: "maven", Language: "java", IsLock: true},

	"build.gradle.kts": {Type: "build.gradle.kts", Ecosystem: "maven", Language: "kotlin", IsLock: false},

	"composer.json": {Type: "composer.json", Ecosystem: "composer", Language: "php", IsLock: false},
	"composer.lock": {Type: "composer.lock", Ecosystem: "composer", Language: "php", IsLock: true},

	"packages.lock.json": {Type: "packages.lock.json", Ecosystem: "nuget", Language: "c#", IsLock: true},
	"paket.dependencies": {Type: "paket.dependencies", Ecosystem: "nuget", Language: "c#", IsLock: false},
	"paket.lock":         {Type: "paket.lock", Ecosystem: "nuget", Language: "c#", IsLock: true},

	"Package.swift":    {Type: "Package.swift", Ecosystem: "swift", Language: "swift", IsLock: false},
	"Package.resolved": {Type: "Package.resolved", Ecosystem: "swift", Language: "swift", IsLock: true},

	"pubspec.yaml": {Type: "pubspec.yaml", Ecosystem: "pub", Language: "dart", IsLock: false},
	"pubspec.lock": {Type: "pubspec.lock", Ecosystem: "pub", Language: "dart", IsLock: true},

	"mix.exs":  {Type: "mix.exs", Ecosystem: "hex", Language: "elixir", IsLock: false},
	"mix.lock": {Type: "mix.lock", Ecosystem: "hex", Language: "elixir", IsLock: true},

	"build.sbt":  {Type: "build.sbt", Ecosystem: "maven", Language: "scala", IsLock: false},
	"build.lock": {Type: "build.lock", Ecosystem: "maven", Language: "scala", IsLock: true},

	"Dockerfile":    {Type: "Dockerfile", Ecosystem: "docker", Language: "docker", IsLock: false},
	"Containerfile": {Type: "Dockerfile", Ecosystem: "docker", Language: "docker", IsLock: false},

	"WORKSPACE":       {Type: "WORKSPACE", Ecosystem: "bazel", Language: "starlark", IsLock: false},
	"WORKSPACE.bazel": {Type: "WORKSPACE", Ecosystem: "bazel", Language: "starlark", IsLock: false},
	"MODULE.bazel":    {Type: "MODULE.bazel", Ecosystem: "bazel", Language: "starlark", IsLock: false},
	"BUCK":            {Type: "BUCK", Ecosystem: "buck", Language: "starlark", IsLock: false},
	"BUCK2":           {Type: "BUCK2", Ecosystem: "buck", Language: "starlark", IsLock: false},

	"conanfile.txt": {Type: "conanfile.txt", Ecosystem: "conan", Language: "c++", IsLock: false},
	"conanfile.py":  {Type: "conanfile.py", Ecosystem: "conan", Language: "c++", IsLock: false},
	"conan.lock":    {Type: "conan.lock", Ecosystem: "conan", Language: "c++", IsLock: true},

	"vcpkg.json": {Type: "vcpkg.json", Ecosystem: "vcpkg", Language: "c++", IsLock: false},

	"Podfile":      {Type: "Podfile", Ecosystem: "cocoapods", Language: "swift", IsLock: false},
	"Podfile.lock": {Type: "Podfile.lock", Ecosystem: "cocoapods", Language: "swift", IsLock: true},

	"Cartfile":          {Type: "Cartfile", Ecosystem: "carthage", Language: "swift", IsLock: false},
	"Cartfile.resolved": {Type: "Cartfile.resolved", Ecosystem: "carthage", Language: "swift", IsLock: true},

	"Project.toml":  {Type: "Project.toml", Ecosystem: "julia", Language: "julia", IsLock: false},
	"Manifest.toml": {Type: "Manifest.toml", Ecosystem: "julia", Language: "julia", IsLock: true},

	"shard.yml":  {Type: "shard.yml", Ecosystem: "crystal", Language: "crystal", IsLock: false},
	"shard.lock": {Type: "shard.lock", Ecosystem: "crystal", Language: "crystal", IsLock: true},

	"deno.json": {Type: "deno.json", Ecosystem: "deno", Language: "typescript", IsLock: false},
	"deno.lock": {Type: "deno.lock", Ecosystem: "deno", Language: "typescript", IsLock: true},

	"DESCRIPTION": {Type: "DESCRIPTION", Ecosystem: "cran", Language: "r", IsLock: false},
	"renv.lock":   {Type: "renv.lock", Ecosystem: "cran", Language: "r", IsLock: true},

	"rebar.config": {Type: "rebar.config", Ecosystem: "erlang", Language: "erlang", IsLock: false},
	"rebar.lock":   {Type: "rebar.lock", Ecosystem: "erlang", Language: "erlang", IsLock: true},

	"stack.yaml": {Type: "stack.yaml", Ecosystem: "stack", Language: "haskell", IsLock: false},

	"cabal.project.freeze": {Type: "cabal.project.freeze", Ecosystem: "cabal", Language: "haskell", IsLock: true},

	"opam": {Type: "opam", Ecosystem: "opam", Language: "ocaml", IsLock: false},

	"flake.nix":  {Type: "flake.nix", Ecosystem: "nix", Language: "nix", IsLock: false},
	"flake.lock": {Type: "flake.lock", Ecosystem: "nix", Language: "nix", IsLock: true},

	"build.zig.zon": {Type: "build.zig.zon", Ecosystem: "zig", Language: "zig", IsLock: false},

	"CPM.cmake": {Type: "CPM.cmake", Ecosystem: "cpm", Language: "cmake", IsLock: false},

	"meson.build": {Type: "meson.build", Ecosystem: "meson", Language: "c", IsLock: false},
}

ManifestFiles maps known manifest filenames (exact basename) to their metadata.

View Source
var SupportedManifestTypes = map[string]bool{

	"package.json":      true,
	"package-lock.json": true,
	"yarn.lock":         true,
	"pnpm-lock.yaml":    true,

	"pyproject.toml":   true,
	"requirements.txt": true,
	"requirements.in":  true,
	"Pipfile":          true,
	"Pipfile.lock":     true,
	"poetry.lock":      true,
	"uv.lock":          true,

	"go.sum": true,
	"go.mod": true,

	"Gemfile":      true,
	"Gemfile.lock": true,

	"Cargo.toml": true,
	"Cargo.lock": true,

	"pom.xml":          true,
	"build.gradle":     true,
	"gradle.lockfile":  true,
	"build.gradle.kts": true,

	"composer.json": true,
	"composer.lock": true,

	"packages.lock.json": true,
	"paket.dependencies": true,
	"paket.lock":         true,
	"*.csproj":           true,

	"Package.swift":    true,
	"Package.resolved": true,

	"pubspec.yaml": true,
	"pubspec.lock": true,

	"mix.exs":  true,
	"mix.lock": true,

	"build.sbt":  true,
	"build.lock": true,

	"Dockerfile": true,

	"*.tf": true,

	"github-actions.yml": true,

	"conanfile.txt": true,
	"conan.lock":    true,

	"vcpkg.json": true,

	"Podfile":      true,
	"Podfile.lock": true,

	"Cartfile":          true,
	"Cartfile.resolved": true,

	"Project.toml":  true,
	"Manifest.toml": true,

	"shard.yml":  true,
	"shard.lock": true,

	"deno.json": true,
	"deno.lock": true,

	"DESCRIPTION": true,
	"renv.lock":   true,

	"rebar.config": true,
	"rebar.lock":   true,

	"stack.yaml": true,

	"*.cabal":              true,
	"cabal.project.freeze": true,

	"*.opam": true,
	"opam":   true,

	"flake.nix":  true,
	"flake.lock": true,

	"build.zig.zon": true,

	"meson.build": true,

	"WORKSPACE":    true,
	"MODULE.bazel": true,

	"BUCK":  true,
	"BUCK2": true,

	"CPM.cmake":      true,
	"CMakeLists.txt": true,
}

SupportedManifestTypes lists manifest types that have a local parser implemented. Files detected but absent from this map are shown as "[not supported]" in scan output.

View Source
var ValidExploitThresholds = []string{"poc", "active", "weaponized"}

ValidExploitThresholds lists the accepted values for the --exploits flag, in ascending order of exploit maturity (least → most dangerous).

View Source
var ValidSeverityThresholds = []string{"low", "medium", "high", "critical"}

ValidSeverityThresholds lists the accepted --severity flag values in ascending order.

Functions

func BuildPayload added in v1.13.2

func BuildPayload(file DetectedFile, gitCtx *gitctx.GitContext, repoRoot string) ([]byte, error)

BuildPayload constructs a ScanPayload for a manifest file and marshals it to JSON. gitCtx may be nil (non-git directory). repoRoot may be empty.

func ComputeEnrichedSeverities added in v1.23.0

func ComputeEnrichedSeverities(ev *EnrichedVuln)

ComputeEnrichedSeverities fills the per-source severity fields and MaxSeverity on ev after all score data has been populated.

func ExploitMeetsThreshold added in v1.35.0

func ExploitMeetsThreshold(ev EnrichedVuln, threshold string) bool

ExploitMeetsThreshold reports whether ev's exploit signals reach the given tier.

Tiers form a strict hierarchy — each tier also captures all higher-maturity signals:

poc       : any public exploit exists (ExploitCount > 0, or any KEV entry)
active    : known active exploitation (InCisaKev || InVulnCheckKev || InEuKev || HasWeaponized)
weaponized: weaponised in-the-wild (ExploitIntel.HasWeaponized)

func HasAnyKev added in v1.35.0

func HasAnyKev(ev EnrichedVuln) bool

HasAnyKev returns true if the vulnerability is listed in any KEV catalog (CISA, VulnCheck, or EU ENISA).

func IsVersionAffected added in v1.21.0

func IsVersionAffected(installedVersion, versionRange, ecosystem string) bool

IsVersionAffected checks whether installedVersion falls within the affected version range string returned by the VDB API.

Supported range formats:

">= 2.0.0, < 2.3.1"     comma-separated constraints
"[2.0.0, 2.3.1)"         interval notation
"< 3.0.0"                single constraint
"2.3.1"                  exact version match

Returns true if the installed version IS affected. When parsing fails the function returns true (assume affected) to err on the side of caution.

func IsVersionSpecPinned added in v1.35.0

func IsVersionSpecPinned(spec string) bool

IsVersionSpecPinned reports whether spec represents an exact version pin. An empty spec (e.g. lock-file entries) is treated as pinned. Specs that begin with range operators (^, ~, >=, >, <=, <, !=) or are symbolic (*, latest, x) are considered unpinned.

func LookupVulns added in v1.21.0

func LookupVulns(
	ctx context.Context,
	client *vdb.Client,
	packages []ScopedPackage,
	concurrency int,
	progress func(done, total int),
) ([]VulnFinding, *LookupStats, error)

LookupVulns queries the VDB API for vulnerabilities affecting the given packages. It deduplicates by (name, ecosystem) and runs lookups with bounded concurrency. The progress callback is called with (done, total) after each package is processed.

Packages with names shorter than 3 characters are skipped (VDB search minimum).

On partial failure (e.g. rate limit hit midway), any results collected before the error are returned alongside the error so the caller can decide whether to use them. Stats always reflect the full picture.

func NormaliseReleaseForEOL added in v1.35.0

func NormaliseReleaseForEOL(product, version string) string

NormaliseReleaseForEOL reduces a full version string to the form expected by the VDB EOL API for the given product.

go     : major.minor  ("1.21.3" → "1.21",  "1.21" → "1.21")
nodejs : major only   ("18.20.4" → "18",   "18" → "18")
python : major.minor  ("3.10.4"  → "3.10", "3.10" → "3.10")
ruby   : major.minor  ("3.2.1"   → "3.2",  "3.2"  → "3.2")

Returns "" if the version string cannot be parsed.

func ParseRemediationScores added in v1.23.0

func ParseRemediationScores(data map[string]interface{}, ev *EnrichedVuln)

ParseRemediationScores extracts scores from the remediation plan response into the EnrichedVuln. These are displayed but not used for primary sorting.

func PopulateInstalledEdges added in v1.35.1

func PopulateInstalledEdges(groups []ManifestGroup, rootPath string)

PopulateInstalledEdges attempts to build dependency graph edges for each manifest group by reading locally installed package manifests. This enriches both SBOM dependency trees and --paths output. Errors are silently skipped.

func SSVCToSeverity added in v1.21.0

func SSVCToSeverity(decision string) string

SSVCToSeverity maps an SSVC decision string to an approximate severity label. SSVC decisions are: Act, Attend, Track*, Track, Defer.

func ScopeIcon added in v1.21.0

func ScopeIcon(scope string) string

ScopeIcon returns a display icon for a scope category.

func ScoreToSeverity added in v1.21.0

func ScoreToSeverity(scoreType string, score float64) string

ScoreToSeverity converts a numeric score of a given type to a severity label. Supported types: epss, coalition_ess (cess), cvss* variants. Returns "unscored" when the type is unrecognised or the score is zero.

func SeverityLevel added in v1.21.0

func SeverityLevel(severity string) int

SeverityLevel returns a numeric level for severity (higher = more severe). This is the inverse of SeverityRank and is used for threshold comparisons.

unscored → 0
low      → 1
medium   → 2
high     → 3
critical → 4

func SeverityMeetsThreshold added in v1.21.0

func SeverityMeetsThreshold(severity, threshold string) bool

SeverityMeetsThreshold reports whether the given severity meets or exceeds the threshold severity. "unscored" never triggers the threshold. Examples:

SeverityMeetsThreshold("critical", "high")  → true
SeverityMeetsThreshold("medium",   "high")  → false
SeverityMeetsThreshold("high",     "high")  → true
SeverityMeetsThreshold("unscored", "low")   → false

func SeverityRank added in v1.13.0

func SeverityRank(severity string) int

SeverityRank returns a numeric rank for severity (lower = more severe). Kept for backward-compatibility; prefer SeverityLevel for threshold logic.

Types

type CLIInfo added in v1.13.2

type CLIInfo struct {
	Version  string `json:"version"`
	Platform string `json:"platform"`
}

CLIInfo identifies the CLI version and platform.

type DepGraph added in v1.21.0

type DepGraph struct {
	DirectDeps map[string]ScopedPackage // name → direct dependency
	AllDeps    map[string]ScopedPackage // name → any dependency (direct or transitive)
	Edges      map[string][]string      // parent module name → child module names (from go mod graph, etc.)
}

DepGraph tracks direct vs transitive dependency relationships for a manifest group. A manifest group is a set of related files in the same directory (e.g., go.mod + go.sum).

func BuildGenericDepGraph added in v1.23.2

func BuildGenericDepGraph(directPkgs, lockPkgs []ScopedPackage) *DepGraph

BuildGenericDepGraph is a generic build graph correlator for ecosystems that have a simple direct manifest + lock file relationship (e.g., Cargo.toml/Cargo.lock).

func BuildGoDepGraph added in v1.21.0

func BuildGoDepGraph(goModPkgs, goSumPkgs []ScopedPackage) *DepGraph

BuildGoDepGraph correlates go.mod (direct) and go.sum (all) packages from the same directory to determine which dependencies are direct vs transitive.

func BuildNpmDepGraph added in v1.21.0

func BuildNpmDepGraph(pkgJsonPkgs, lockPkgs []ScopedPackage) *DepGraph

BuildNpmDepGraph correlates package.json (direct) and package-lock.json (all) packages from the same directory.

func BuildPypiDepGraph added in v1.22.0

func BuildPypiDepGraph(directPkgs, lockPkgs []ScopedPackage) *DepGraph

BuildPypiDepGraph correlates pyproject.toml (direct) and lock files (uv.lock, poetry.lock, Pipfile.lock) to classify direct vs transitive dependencies. Package name comparison is case-folded and normalises dashes/underscores to handle the common PyPI naming quirks.

func (*DepGraph) DirectCount added in v1.21.0

func (g *DepGraph) DirectCount() int

DirectCount returns the number of direct dependencies.

func (*DepGraph) FindPath added in v1.21.0

func (g *DepGraph) FindPath(targetPkg string) []string

FindPath returns the shortest dependency chain from any direct dep to targetPkg. Returns nil if no path exists or edge data is unavailable. The returned slice is the chain: [direct-dep, intermediate, ..., targetPkg].

func (*DepGraph) IsDirect added in v1.21.0

func (g *DepGraph) IsDirect(pkgName string) bool

IsDirect returns true if the package was declared directly in the manifest. For PyPI packages, name lookup is also attempted with dash/underscore/case normalisation so that e.g. "PyYAML" matches a key stored as "pyyaml".

func (*DepGraph) PopulateGoModGraph added in v1.21.0

func (g *DepGraph) PopulateGoModGraph(dir string) error

PopulateGoModGraph runs "go mod graph" in the given directory and populates the Edges map with the dependency relationships. Strips version suffixes so edges use bare module names matching package names.

func (*DepGraph) PopulateNpmLockEdges added in v1.34.0

func (g *DepGraph) PopulateNpmLockEdges(lockFilePath string) error

PopulateNpmLockEdges parses package-lock.json (v2/v3) and populates the Edges map from the nested node_modules path structure. In v3 format, the key "node_modules/foo/node_modules/bar" means foo depends on bar.

func (*DepGraph) TransitiveCount added in v1.21.0

func (g *DepGraph) TransitiveCount() int

TransitiveCount returns the number of transitive (non-direct) dependencies.

type DetectedFile

type DetectedFile struct {
	Path         string
	RelPath      string // relative to scan root
	FileType     FileType
	ManifestInfo *ManifestInfo // non-nil for manifest files
	SBOMVersion  string        // e.g. "SPDX-2.3", "1.5" for CycloneDX
	Supported    bool          // whether the backend accepts this file type
}

DetectedFile represents a detected scannable file

func WalkForScanFiles

func WalkForScanFiles(opts WalkOptions) ([]DetectedFile, error)

WalkForScanFiles walks the filesystem from root, up to maxDepth, looking for manifest files and potential SBOM documents.

type EnrichedVuln added in v1.21.0

type EnrichedVuln struct {
	VulnFinding
	Confirmed       bool    // true if installed version is in affected range
	IsMalicious     bool    // malware/malicious package — highest sort priority
	AffectedRange   string  // e.g., ">= 2.0.0, < 2.3.1"
	PathCount       int     // number of source files / transitive paths introducing this vuln
	ThreatExposure  float64 // x_threatExposure from VDB — primary sort key
	EPSSScore       float64 // displayed
	EPSSPercentile  float64 // displayed
	CVSSScore       float64 // displayed
	CoalitionESS    float64 // displayed
	ExploitIntel    *ExploitSummary
	Remediation     *RemediationInfo
	SSVCDecision    string // "Act", "Attend", "Track*", "Track"
	FixAvailability string // "available", "partial", "no_fix"
	IDSRules        []IDSRule

	// Per-source severity ratings (coerced from numeric scores / decisions).
	EPSSSeverity string // severity derived from EPSS probability
	CESSeverity  string // severity derived from Coalition ESS score
	CVSSSeverity string // severity derived from CVSS score
	SSVCSeverity string // severity derived from SSVC decision
	// MaxSeverity is the highest severity across all scoring sources for this vuln.
	// It is used for --severity threshold evaluation.
	MaxSeverity string

	// MatchMethod records how this vuln was matched to the package (e.g. "name+version", "cpe", "name-only").
	MatchMethod string
}

EnrichedVuln extends VulnFinding with version-filtered, enriched data.

func EnrichVulns added in v1.21.0

func EnrichVulns(
	ctx context.Context,
	v1Client *vdb.Client,
	v2Client *vdb.Client,
	findings []VulnFinding,
	packages []ScopedPackage,
	concurrency int,
	progress func(done, total int),
) ([]EnrichedVuln, error)

EnrichVulns filters vulnerabilities by affected version range (via V2Affected), fetches exploit intelligence and remediation plans, and deduplicates by (CveID, PkgName).

type ExploitSummary added in v1.21.0

type ExploitSummary struct {
	ExploitCount    int
	Sources         []string
	HasWeaponized   bool
	HighestMaturity string
}

ExploitSummary captures exploit intelligence for a vulnerability.

type FileType

type FileType string

FileType represents the detected type of a file

const (
	FileTypeManifest  FileType = "manifest"
	FileTypeSPDX      FileType = "spdx"
	FileTypeCycloneDX FileType = "cyclonedx"
	FileTypeUnknown   FileType = "unknown"
)

func DetectSBOM

func DetectSBOM(filePath string) (FileType, string, bool)

DetectSBOM reads the first bytes of a JSON file and determines if it's an SPDX or CycloneDX document. Returns the file type, version string, and whether it's valid/supported.

type FixesMerged added in v1.13.0

type FixesMerged struct {
	Registry      map[string]interface{}
	Distributions map[string]interface{}
	Source        map[string]interface{}
}

FixesMerged holds merged fix data from three V2 endpoints.

type IDSRule added in v1.21.0

type IDSRule struct {
	Type    string // "snort" or "suricata"
	Content string
	Source  string
	CveID   string
}

IDSRule represents a snort or suricata detection rule.

func CollectIDSRules added in v1.21.0

func CollectIDSRules(vulns []EnrichedVuln) []IDSRule

CollectIDSRules gathers all IDS rules from enriched vulns.

type LookupStats added in v1.25.0

type LookupStats struct {
	Total     int // unique packages queried (after dedup)
	Succeeded int // API calls that returned successfully
	Failed    int // API calls that returned an error
	Skipped   int // packages skipped (name too short)
	Cancelled int // packages not attempted (cancelled after fatal error)
}

LookupStats summarises the outcome of a LookupVulns call.

type ManifestGroup added in v1.21.0

type ManifestGroup struct {
	Dir       string          // relative directory
	Ecosystem string          // e.g., "golang", "npm"
	Files     []string        // relative paths of constituent manifest files
	Graph     *DepGraph       // direct vs transitive classification
	Packages  []ScopedPackage // all packages from this group
}

ManifestGroup holds related manifest files from the same directory/ecosystem.

func BuildManifestGroups added in v1.21.0

func BuildManifestGroups(filePackages map[string][]ScopedPackage, fileEcosystems map[string]string) []ManifestGroup

BuildManifestGroups correlates manifest results by directory and ecosystem, building dependency graphs where possible.

type ManifestInfo

type ManifestInfo struct {
	Type      string // canonical filename used as the manifest "type" parameter
	Ecosystem string
	Language  string
	IsLock    bool
}

ManifestInfo describes a known manifest file

func DetectManifest

func DetectManifest(filename string) (*ManifestInfo, bool)

DetectManifest checks if a file is a known manifest. It checks in order: exact basename → file extension → path pattern (GitHub Actions).

type PackageLookupKey added in v1.21.0

type PackageLookupKey struct {
	Name      string
	Ecosystem string
}

PackageLookupKey uniquely identifies a package by name and ecosystem.

type PollEngine added in v1.13.0

type PollEngine struct {
	Client     *vdb.Client
	Interval   time.Duration   // polling interval (default 5s)
	OnProgress func(*ScanTask) // callback for UI updates (called from goroutines)
}

PollEngine handles concurrent polling for scan results.

func (*PollEngine) PollAll added in v1.13.0

func (p *PollEngine) PollAll(ctx context.Context, tasks []*ScanTask)

PollAll polls all tasks with a scan ID until they are complete or errored. Tasks without a scan ID are skipped.

type RemediationInfo added in v1.21.0

type RemediationInfo struct {
	FixAvailability string
	FixVersion      string
	Actions         []string
}

RemediationInfo captures remediation plan details.

type RuntimePin added in v1.35.0

type RuntimePin struct {
	Product    string // VDB EOL product name: "go", "nodejs", "python", "ruby"
	Release    string // normalised for the EOL API: "1.21", "18", "3.10"
	RawVersion string // raw version string from the file
	SourceFile string // relative path of the pin file within the project root
}

RuntimePin records a runtime version detected from a version-pin file.

func DetectRuntimeVersionPins added in v1.35.0

func DetectRuntimeVersionPins(rootPath string) []RuntimePin

DetectRuntimeVersionPins scans rootPath for common runtime version-pin files and returns the detected runtime versions. Only the project root is inspected (no recursion). Errors reading individual files are silently skipped.

Files inspected: go.mod, .nvmrc, .node-version, .python-version, .tool-versions, .ruby-version, Gemfile, Dockerfile, Containerfile. LTS aliases in .nvmrc (e.g. "lts/hydrogen") are silently skipped.

type ScanError added in v1.13.0

type ScanError struct {
	Message string
}

ScanError represents a scan-side error returned by the API.

func (*ScanError) Error added in v1.13.0

func (e *ScanError) Error() string

type ScanPayload added in v1.13.2

type ScanPayload struct {
	Version      string                    `json:"version"`
	CLI          CLIInfo                   `json:"cli"`
	Git          *gitctx.GitContext        `json:"git,omitempty"`
	FileTree     *filetree.FileTreeContext `json:"fileTree,omitempty"`
	ManifestType string                    `json:"manifestType"`
	Ecosystem    string                    `json:"ecosystem"`
	Timestamp    int64                     `json:"timestamp"`
}

ScanPayload is the JSON metadata sent alongside manifest files.

type ScanSummary added in v1.13.0

type ScanSummary struct {
	TotalFiles    int
	TotalVulns    int
	MalwareCount  int
	CriticalCount int
	HighCount     int
	MediumCount   int
	LowCount      int
	ErrorCount    int
}

ScanSummary aggregates results across all tasks.

func Summarize added in v1.13.0

func Summarize(tasks []*ScanTask) ScanSummary

Summarize computes a summary from completed scan tasks.

func (ScanSummary) FormatSummary added in v1.13.0

func (s ScanSummary) FormatSummary() string

FormatSummary returns a human-readable summary string.

type ScanTask added in v1.13.0

type ScanTask struct {
	File        DetectedFile
	ScanID      string
	Status      string // "queued","uploading","uploaded","polling","complete","error"
	UploadStart time.Time
	UploadEnd   time.Time
	PollStart   time.Time
	PollEnd     time.Time
	Error       error
	RawResult   map[string]interface{}
	Vulns       []VulnSummary
}

ScanTask tracks one file's lifecycle through upload -> poll -> results.

func (*ScanTask) PollDuration added in v1.13.0

func (t *ScanTask) PollDuration() time.Duration

PollDuration returns the time spent polling.

func (*ScanTask) TotalDuration added in v1.13.0

func (t *ScanTask) TotalDuration() time.Duration

TotalDuration returns the total time from upload start to poll completion.

func (*ScanTask) UploadDuration added in v1.13.0

func (t *ScanTask) UploadDuration() time.Duration

UploadDuration returns the time spent uploading.

type ScopedPackage added in v1.21.0

type ScopedPackage struct {
	Name        string
	Version     string
	VersionSpec string // raw version spec from manifest before cleaning (e.g. "^1.0.0", ">=2.3"); empty for lock-file entries
	Ecosystem   string
	Scope       string // native scope label (production, development, test, peer, etc.)
	SourceFile  string // relative path of the manifest file that declared this package
	IsDirect    bool   // true if declared in the manifest (e.g., go.mod), false if transitive (e.g., go.sum)
	GitHubURL   string // optional: "owner/repo" for packages whose VCS is known from the manifest
}

ScopedPackage represents a parsed dependency with scope information.

func ParseManifestWithScope added in v1.21.0

func ParseManifestWithScope(filePath, manifestType string) ([]ScopedPackage, error)

ParseManifestWithScope parses a manifest file and returns packages with scope information. It uses the file's manifest type to choose the appropriate parser.

type ScoreEntry added in v1.13.0

type ScoreEntry struct {
	Type   string // "epss","coalition_ess","cvssv4","cvssv3.1","cvssv3.0","cvssv2"
	Score  float64
	Source string
}

ScoreEntry represents a single vulnerability score.

type UnsupportedFileError added in v1.13.0

type UnsupportedFileError struct {
	Path string
}

UnsupportedFileError is returned when a file type is not supported for upload.

func (*UnsupportedFileError) Error added in v1.13.0

func (e *UnsupportedFileError) Error() string

type UploadEngine added in v1.13.0

type UploadEngine struct {
	Client      *vdb.Client
	Concurrency int                // max concurrent uploads (default 5)
	OnProgress  func(*ScanTask)    // callback for UI updates (called from goroutines)
	GitContext  *gitctx.GitContext // shared git context (collected once, may be nil)
	RepoRoot    string             // git repo root path (may be empty)
}

UploadEngine handles concurrent file uploads to the VDB API.

func (*UploadEngine) UploadAll added in v1.13.0

func (e *UploadEngine) UploadAll(ctx context.Context, files []DetectedFile) []*ScanTask

UploadAll uploads all detected files concurrently using a bounded semaphore. Returns a ScanTask for each file with status "uploaded" or "error".

type VulnFinding added in v1.21.0

type VulnFinding struct {
	CveID          string
	PackageName    string
	PackageVer     string
	Ecosystem      string
	Scope          string
	Severity       string
	Score          float64
	MetricType     string
	VectorString   string
	SourceFile     string
	Source         string // upstream vulnerability source name (empty = vulnetix)
	InCisaKev      bool
	InVulnCheckKev bool
	InEuKev        bool
	ExploitCount   int
}

VulnFinding represents a vulnerability found during a local scan.

type VulnSummary added in v1.13.0

type VulnSummary struct {
	VulnID      string
	IsMalicious bool
	Scores      []ScoreEntry // ordered: EPSS > Coalition ESS > CVSSv4 > CVSS3 > CVSS2
	Severity    string
	PackageName string
	PackageVer  string
	SourceFile  string // which scanned file this came from
	// Lazy-loaded detail fields (nil until fetched)
	Exploits    *map[string]interface{}
	Timeline    *map[string]interface{}
	Fixes       *FixesMerged
	Remediation *map[string]interface{}
	Advisories  *map[string]interface{}
	Workarounds *map[string]interface{}
	Kev         *map[string]interface{}
}

VulnSummary is a parsed vulnerability from scan results.

func AllVulns added in v1.13.0

func AllVulns(tasks []*ScanTask) []VulnSummary

AllVulns returns all vulnerabilities across all tasks, sorted by severity.

func ParseVulnsFromScanResult added in v1.13.0

func ParseVulnsFromScanResult(raw map[string]interface{}, sourceFile string) []VulnSummary

ParseVulnsFromScanResult extracts vulnerability summaries from a scan status API response.

func (*VulnSummary) TopScore added in v1.13.0

func (v *VulnSummary) TopScore() (string, float64)

TopScore returns the highest-priority score, or 0 if none.

type WalkOptions

type WalkOptions struct {
	RootPath string
	MaxDepth int
	Excludes []string // glob patterns to exclude
}

WalkOptions configures the filesystem walk behavior.

Jump to

Keyboard shortcuts

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