fix(cpe): generate the correct CPE for Microsoft Edge PE binaries - #5212
Open
pujitha24 wants to merge 1 commit into
Open
fix(cpe): generate the correct CPE for Microsoft Edge PE binaries#5212pujitha24 wants to merge 1 commit into
pujitha24 wants to merge 1 commit into
Conversation
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Microsoft Edge PE binaries (
msedge.exe) on Windows were getting a CPE generated straight from the raised package name ("Microsoft Edge"), producingcpe: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(andsyft/format/internal/backfill.go) usep.CPEs[0]as the package's sole CycloneDXcpefield, andsyft/cpe/by_specificity.go's tie-break sorts by combined field character count, so the longerMicrosoft_Edge:Microsoft_Edge(28 chars) always outranked the correctmicrosoft: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 whycandidateVendorsForPE/candidateProductsForPEnow 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 correctmicrosoft:edge_chromiumcandidate 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
Checklist
Issue references
Fixes #4429