A vulnerability scanner for container images and filesystems
This report summarizes scanner evidence for anchore/grype, a Go project with 13,154 GitHub stars. SynthScan examined 201,502 lines of code across 1294 source files, recording 161 pattern matches distributed across 11 syntactic categories. The legacy adjusted pattern signal is 1.0 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 144 finding(s).
Are imports declared and package/API names verified? 4 finding(s).
Are wrappers, guards, and repeated structures necessary? 18 finding(s).
Which changes need focused human review? 161 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 161 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | .golangci.yaml | 61 | # - gochecknoglobals | COMMENT |
| LOW | cmd/grype/cli/options/experimental.go | 1 | package options | COMMENT |
| LOW | cmd/grype/cli/options/match.go | 41 | // dpkgConfig contains configuration for the dpkg matcher. | COMMENT |
| LOW | cmd/grype/cli/options/match.go | 61 | // With "auto": Treat package as 1:2.0.0 → NO MATCH (2.0.0 > 1.5.0) | COMMENT |
| LOW | cmd/grype/cli/commands/internal/dbsearch/versions.go | 1 | package dbsearch | COMMENT |
| LOW | cmd/grype/cli/commands/internal/dbsearch/versions.go | 21 | // VulnerabilitiesSchemaVersion is the schema version for the `db search vuln` command | COMMENT |
| LOW | test/install/test_harness.sh | 181 | # ../../snapshot/grype_0.32.0-SNAPSHOT-e5e847a_linux_arm64.tar.gz | COMMENT |
| LOW | internal/dbtest/assertions.go | 121 | // Matches returns the underlying []match.Match. It is an intentional escape | COMMENT |
| LOW | internal/dbtest/assertions.go | 1141 | found match.DistroResult | COMMENT |
| LOW | internal/dbtest/builder.go | 41 | } | COMMENT |
| LOW | internal/dbtest/builder.go | 101 | cacheDir: cacheDir, | COMMENT |
| LOW | internal/dbtest/cmd/manager/main.go | 1 | // manager is a CLI tool for creating and maintaining test fixtures from vunnel SQLite caches. | COMMENT |
| LOW | .github/workflows/release.yaml | 41 | permissions: | COMMENT |
| LOW | grype/vulnerability_matcher_dropped_test.go | 1 | package grype | COMMENT |
| LOW | grype/vulnerability_matcher_validation_test.go | 161 | WithLocation("/app/vendor/bundle/gems/rack-protection-1.5.3/lib/rack/protection.rb"). | COMMENT |
| LOW | grype/match/ignore_rule_index.go | 1 | package match | COMMENT |
| LOW | grype/match/match_test.go | 421 | COMMENT | |
| LOW | grype/match/ignore.go | 101 | COMMENT | |
| LOW | grype/internal/rootio/cpes.go | 21 | // grype/db/v6/name: syft's CPE generator produces CPEs from the (rootio- | COMMENT |
| LOW | grype/internal/rootio/rootio.go | 1 | // Package rootio detects whether a scanned package was published by Root IO | COMMENT |
| LOW | grype/internal/rootio/rootio.go | 21 | // javaGroupID is consulted only when pkgType is JavaPkg / JenkinsPluginPkg — | COMMENT |
| LOW | grype/internal/rootio/rootio.go | 41 | // collisions are implausible: | COMMENT |
| LOW | grype/internal/rootio/rootio.go | 81 | return strings.TrimPrefix(name, "io.root.") | COMMENT |
| LOW | grype/matcher/apk/matcher.go | 41 | // Everything is reconciled in result.Set space by vulnerability identity -- ID plus aliases -- so | COMMENT |
| LOW | grype/matcher/apk/matcher.go | 181 | } | COMMENT |
| LOW | grype/matcher/apk/rootio_test.go | 21 | // plus the existing alpine318 fixture's CVE-2024-0727 for the standard | COMMENT |
| LOW | grype/matcher/apk/rootio_test.go | 41 | // | COMMENT |
| LOW | grype/matcher/apk/matcher_test.go | 461 | }) | COMMENT |
| LOW | grype/matcher/apk/matcher_test.go | 561 | COMMENT | |
| LOW | grype/matcher/apk/matcher_test.go | 621 | ForPackage(pkgID). | COMMENT |
| LOW | grype/matcher/apk/matcher_test.go | 701 | WithArchitecture("aarch64"). // mismatch: Chainguard APH says x86_64 | COMMENT |
| LOW | grype/matcher/python/matcher_test.go | 101 | Build() | COMMENT |
| LOW | …pe/matcher/python/testdata/python-name-and-vex/db.yaml | 1 | auto-generate: true | COMMENT |
| LOW | grype/matcher/python/testdata/versionless-vex/db.yaml | 1 | # Hand-authored openvex statements with versionless purls, paired with the | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_merge_test.go | 21 | // third-party scenarios (gjson, aws-sdk-go) exercise DB-side merge and range | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_merge_test.go | 41 | // govulndb custom_ranges tag-space window (< 5.21.2) and patches the lxd | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_merge_test.go | 181 | // local names, as syft captures them): the vulnerable constructor (on GO-2022-0635's symbol | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_merge_test.go | 241 | // vulnerable project resource listing function (on GO-2024-3312's symbol list) plus other | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_merge_test.go | 361 | } | COMMENT |
| LOW | grype/matcher/golang/gosymbols_test.go | 21 | // as the go-imports qualifier. GO-2023-1840 lists the whole "runtime" package | COMMENT |
| LOW | grype/matcher/golang/gosymbols_test.go | 141 | // 29405 — cmd/go and cgo flaws that affect the machine that RAN the build, not | COMMENT |
| LOW | grype/matcher/golang/gosymbols_ghsa_bypass_test.go | 21 | // bridging the whole alias group. | COMMENT |
| LOW | grype/matcher/golang/testdata/govulndb-and-ghsa/db.yaml | 1 | # Combined govulndb + github fixture exercising the build-time merge of go | COMMENT |
| LOW | grype/matcher/golang/testdata/govulndb-and-ghsa/db.yaml | 21 | # flag every version) while the GHSA bounds it at < 1.34.0. The merged | COMMENT |
| LOW | grype/matcher/golang/testdata/govulndb-and-ghsa/db.yaml | 41 | # /v9 rows are dropped and the GHSA enriched with symbols; the base//v7//v8 | COMMENT |
| LOW | grype/matcher/internal/cpe_test.go | 1021 | } | COMMENT |
| LOW | grype/matcher/java/matcher_test.go | 141 | require.Error(t, err, "expected rate-limit error") | COMMENT |
| LOW | grype/matcher/java/matcher_test.go | 161 | // surfaces three UnaffectedPackageEntry IgnoreRules - one per | COMMENT |
| LOW | grype/matcher/java/matcher_test.go | 221 | }) | COMMENT |
| LOW | …matcher/javascript/testdata/npm-scope-handling/db.yaml | 1 | auto-generate: true | COMMENT |
| LOW | grype/matcher/rpm/matcher.go | 21 | // flags vulnerabilities that should be suppressed on related packages (e.g., | COMMENT |
| LOW | grype/matcher/rpm/matcher.go | 141 | return almaLinuxMatchesWithUpstreams(provider, binaryPkg) | COMMENT |
| LOW | grype/matcher/rpm/matcher.go | 181 | // not changed their version scheme at all --therefore it is safe to assume that | COMMENT |
| LOW | grype/matcher/rpm/matcher.go | 201 | // the rule from RedHat we should assume a 0 epoch and make the comparison: | COMMENT |
| LOW | grype/matcher/rpm/rhel_multi_rhsa_test.go | 21 | // upstream bases reduced to one record whose VulnerableRange partitions the streams: | COMMENT |
| LOW | grype/matcher/rpm/rhel_multi_rhsa_test.go | 141 | SelectDetailByType(match.ExactIndirectMatch). | COMMENT |
| LOW | grype/matcher/rpm/rhel_multi_rhsa_test.go | 261 | Ignores(). | COMMENT |
| LOW | grype/matcher/rpm/rhel_multi_rhsa_test.go | 361 | COMMENT | |
| LOW | grype/matcher/rpm/rhel_multi_rhsa_test.go | 521 | // exercises the redhatEUSMatches two-fetch path -- unchanged in this branch -- against the | COMMENT |
| LOW | grype/matcher/rpm/rhel_eus_test.go | 841 | // lookup against the EUS-overlay fix, a +eus-distro lookup against the same | COMMENT |
| 61 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | install.sh | 27 | # ------------------------------------------------------------------------ | COMMENT |
| MEDIUM | install.sh | 32 | # ------------------------------------------------------------------------ | COMMENT |
| MEDIUM | install.sh | 286 | # ------------------------------------------------------------------------ | COMMENT |
| MEDIUM | install.sh | 288 | # ------------------------------------------------------------------------ | COMMENT |
| MEDIUM | grype/db/v6/diff/vuln_diff_test.go | 38 | // ── no-change cases ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | grype/db/v6/diff/vuln_diff_test.go | 70 | // ── CVE (vulnerability_handles) add/remove/modify ────────────────── | COMMENT |
| MEDIUM | grype/db/v6/diff/vuln_diff_test.go | 135 | // ── KEV-only diffs (CVEs with only KEV entries, no NVD) ──────────── | COMMENT |
| MEDIUM | grype/db/v6/diff/vuln_diff_test.go | 186 | // ── EPSS diffs (CVEs with NVD + EPSS data) ──────────────────────── | COMMENT |
| MEDIUM | grype/db/v6/diff/vuln_diff_test.go | 230 | // ── Combined KEV + EPSS + CVE changes ───────────────────────────── | COMMENT |
| MEDIUM | grype/db/internal/provider/unmarshal/csaf_vex.go | 14 | // ── document metadata ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | grype/db/internal/provider/unmarshal/csaf_vex.go | 90 | // ── product tree ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | grype/db/internal/provider/unmarshal/csaf_vex.go | 122 | // ── vulnerabilities ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | grype/db/internal/provider/unmarshal/csaf_vex.go | 195 | // ── unmarshal entry point ──────────────────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | grype/presenter/cyclonedx/vulnerability.go | 75 | // TODO: we do not leverage the following fields in our model | COMMENT |
| MEDIUM | grype/matcher/internal/only_vulnerable_targets.go | 19 | // TODO: in the future this should be moved to underneath the store to avoid the need to recompute CPE comparisons and t | COMMENT |
| MEDIUM | grype/db/v6/data.go | 41 | // Why 6.0.3? This is when OS channel was introduced, which grype-db will leverage, and add additional | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | grype/matcher/rpm/almalinux.go | 66 | // Step 1: Find RHEL disclosures for the binary package (direct match) | COMMENT |
| LOW | grype/matcher/rpm/almalinux.go | 79 | // Step 2: Find RHEL disclosures for upstream (source) packages (indirect match) | COMMENT |
| LOW | grype/matcher/rpm/almalinux.go | 115 | // Step 3: Find AlmaLinux unaffected records for the binary package | COMMENT |
| LOW⚡ | grype/matcher/rpm/almalinux.go | 128 | // Step 4: Find AlmaLinux unaffected records for related packages (source/binary relationships) | COMMENT |
| LOW⚡ | grype/matcher/rpm/almalinux.go | 136 | // Step 5: Apply filtering logic: if disclosure exists and no fix applies, the package is vulnerable | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | grype/matcher/rpm/almalinux.go | 66 | // Step 1: Find RHEL disclosures for the binary package (direct match) | COMMENT |
| LOW | grype/matcher/rpm/almalinux.go | 79 | // Step 2: Find RHEL disclosures for upstream (source) packages (indirect match) | COMMENT |
| LOW | grype/matcher/rpm/almalinux.go | 115 | // Step 3: Find AlmaLinux unaffected records for the binary package | COMMENT |
| LOW⚡ | grype/matcher/rpm/almalinux.go | 128 | // Step 4: Find AlmaLinux unaffected records for related packages (source/binary relationships) | COMMENT |
| LOW⚡ | grype/matcher/rpm/almalinux.go | 136 | // Step 5: Apply filtering logic: if disclosure exists and no fix applies, the package is vulnerable | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | test/install/test_harness.sh | 125 | # if you want to see proof in the logs, feel free to adjust the redirection | COMMENT |
| MEDIUM | grype/vex/testdata/vex-docs/csaf-demo2.json | 8 | "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", | CODE |
| MEDIUM | grype/vex/testdata/vex-docs/csaf-demo1.json | 8 | "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | test/validate-grype-db-schema.py | 12 | def report_schema_versions_found(title, schema_to_locations): | CODE |
| LOW | test/validate-grype-db-schema.py | 20 | def assert_single_schema_version(schema_to_locations): | CODE |
| LOW⚡ | test/validate-grype-db-schema.py | 69 | def assert_schema_version_prefix(schema, locations): | CODE |
| LOW⚡ | test/validate-grype-db-schema.py | 75 | def validate_schema_consumers(): | CODE |
| LOW⚡ | test/validate-grype-db-schema.py | 82 | def validate_schema_definitions(): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | grype/presenter/cyclonedx/testdata/bom-1.6.schema.json | 904 | "examples": ["Acme Inc"] | CODE |
| LOW | grype/presenter/cyclonedx/testdata/bom-1.6.schema.json | 910 | "examples": ["Acme Inc"] | CODE |
| LOW | grype/presenter/cyclonedx/testdata/bom-1.6.schema.json | 964 | "examples": ["Acme Inc"] | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cmd/grype/cli/commands/explain.go | 53 | // TODO: implement | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | test/validate-grype-db-schema.py | 34 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | grype/db/v5/distribution/testdata/tls/listing.py | 1 | CODE |