Skip to content

fix(cpe): generate the correct CPE for Microsoft Edge PE binaries - #5212

Open
pujitha24 wants to merge 1 commit into
anchore:mainfrom
pujitha24:auto/issue-4429
Open

fix(cpe): generate the correct CPE for Microsoft Edge PE binaries#5212
pujitha24 wants to merge 1 commit into
anchore:mainfrom
pujitha24:auto/issue-4429

Conversation

@pujitha24

Copy link
Copy Markdown
Contributor

Description

Microsoft Edge PE binaries (msedge.exe) on Windows were getting a CPE generated straight from the raised package name ("Microsoft Edge"), producing cpe:2.3:a:Microsoft_Edge:Microsoft_Edge:<version>:*:*:*:*:*:*:* instead of the NVD dictionary's actual entry, cpe:2.3:a:microsoft:edge_chromium:<version>:*:*:*:*:*:*:*.

This adds PE metadata hints for Edge in syft/pkg/cataloger/internal/cpegenerate/candidate_for_pe.go, following the existing Ghostscript/Git-for-Windows pattern in that file, per the fix location a maintainer pointed at in the issue thread.

The mismatched candidate wasn't merely "less accurate" — it consistently ranked first. syft/format/internal/cyclonedxutil/helpers/cpe.go (and syft/format/internal/backfill.go) use p.CPEs[0] as the package's sole CycloneDX cpe field, and syft/cpe/by_specificity.go's tie-break sorts by combined field character count, so the longer Microsoft_Edge:Microsoft_Edge (28 chars) always outranked the correct microsoft:edge_chromium (22 chars). Because of this, adding the correct candidate alongside the existing default wasn't sufficient on its own — the incorrect default also had to be cleared for the Edge case, which is why candidateVendorsForPE/candidateProductsForPE now mutate the caller's candidate set in place instead of returning one to union in (documented in a comment, since this is a deliberate small deviation from sibling helpers in the same package). For SPDX (external_refs.go), which emits all generated CPEs rather than just the first, this fix isn't just about ordering — previously the correct microsoft:edge_chromium candidate wasn't generated at all.

Net effect: syft scan (and any consumer of its CycloneDX/SPDX output, e.g. Grype or Dependency-Track) now generates a CPE for Edge that actually matches the NVD CPE dictionary entry, so CVEs for Microsoft Edge can be matched correctly. This is a CPE-generation correctness fix, not a crash or a vulnerability in Syft itself — the prior behavior silently produced a non-matching CPE, causing downstream vulnerability scanners to false-negative on Edge CVEs.

No CLI flags or output schema changes; only the generated CPE values change for this specific binary.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have added unit tests that cover changed behavior
  • I have tested my code in common scenarios and confirmed there are no regressions
  • I have added comments to my code, particularly in hard-to-understand sections

Issue references

Fixes #4429

Motivation:
Microsoft Edge PE binaries (msedge.exe) on Windows produced a CPE
generated verbatim from the raised package name ("Microsoft Edge"),
yielding cpe:2.3:a:Microsoft_Edge:Microsoft_Edge:<version>:... instead
of the NVD CPE dictionary's actual entry,
cpe:2.3:a:microsoft:edge_chromium:<version>:.... Since
syft/format/internal/cyclonedxutil/helpers/cpe.go and
syft/format/internal/backfill.go use p.CPEs[0] as the package's sole
CycloneDX CPE, and syft/cpe/by_specificity.go's tie-break sorts by
combined field character count, the longer, incorrect
"Microsoft_Edge:Microsoft_Edge" candidate always outranked the correct,
shorter "microsoft:edge_chromium" one and was the value actually
emitted. This causes downstream vulnerability scanners (e.g. Grype,
Dependency-Track) consuming syft's output to false-negative on Edge
CVEs, since the emitted CPE never matches NVD's dictionary entry.

Approach:
Add a Microsoft Edge hint to
syft/pkg/cataloger/internal/cpegenerate/candidate_for_pe.go, following
the existing Ghostscript/Git-for-Windows pattern already in that file.
Because the incorrect default candidate was winning on specificity,
simply adding a better candidate alongside it (the prior union-only
behavior) was not enough - the incorrect default also needs to be
cleared. candidateVendorsForPE/candidateProductsForPE now mutate the
caller's candidate set in place (documented inline as a deliberate,
minor deviation from sibling helpers in the same package, which return
a fresh set to union in) so the Edge case can clear() the caller's
existing candidates before adding the correct microsoft/edge_chromium
pair. The added candidates disallow delimiter variations so a derived
"edge-chromium" hyphenated form can't out-rank the underscore form
NVD actually uses. The match is an exact, case-insensitive comparison
against "microsoft edge" (not a substring match) so it does not
misfire on related-but-distinct binaries such as Edge Beta/Dev or
WebView2, which have different real CPEs.

Validation:
go build ./... passed. go test
./syft/pkg/cataloger/internal/cpegenerate/... passed, including a new
targeted test (TestMicrosoftEdgePEGeneratesCorrectCPE) built on
synthetic PE VersionResources metadata mirroring the existing
Ghostscript test's approach; it asserts the primary CPE (index 0, the
one actually emitted to CycloneDX) has vendor "microsoft" and product
"edge_chromium", and that no CPE in the full candidate list is derived
verbatim from the raised package name. golangci-lint run (repo's own
.golangci.yaml) against the changed package reported zero issues in
the changed files. gofmt -l on the changed files was clean. I could not
run go test ./syft/pkg/cataloger/binary/... in this sandbox (Docker is
unavailable for its image-fixture-based subtests unrelated to this
change; confirmed pre-existing by reproducing the identical failure
against an unmodified checkout). I did not reproduce this against a
live msedge.exe binary; the fix is validated via a targeted synthetic
unit test built from realistic PE VersionResources metadata (Company:
"Microsoft Corporation", ProductName/FileDescription: "Microsoft
Edge"), matching this repo's existing testing convention for this file.

Report: anchore#4429
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: claude-sonnet-5 (via Claude Code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect CPE for Edge on Windows

1 participant