Skip to content

fix: compare CPython CPE versions using Python ordering - #3776

Open
BarakStout wants to merge 3 commits into
anchore:mainfrom
BarakStout:fix/cpython-cpe-prerelease-ordering
Open

BarakStout wants to merge 3 commits into
anchore:mainfrom
BarakStout:fix/cpython-cpe-prerelease-ordering

Conversation

@BarakStout

@BarakStout BarakStout commented Oct 9, 2026 •

Copy link
Copy Markdown

What does this PR do?

Use Python's existing PEP 440 comparator for recognized CPython application CPEs (python:python and python_software_foundation:python), independent of whether the interpreter was cataloged as a binary or a distribution package.

CPython 3.15.0 is newer than 3.15.0a6, but the existing generic/APK comparison treats the final release as earlier than the letter-suffixed prerelease. That produces a false positive for CVE-2025-15367 with its NVD bound < 3.15.0a6. The CNA record explicitly identifies the version type as python.

This changes comparison semantics for those CPython CPEs only. It does not modify package/CPE versions, vulnerability data, ignore rules or other products' comparison behavior. OpenSSL letter suffixes retain their existing meaning.

Testing

  • Added the actual CVE boundary for both CPython CPE vendors and binary/APK packages, covering an older stable version, alpha 5, alpha 6, beta, RC, final 3.15.0 and 3.15.1.
  • Added OpenSSL 1.0.2/1.0.2k/1.0.2l/1.0.2m controls.
  • Before the fix, all four final 3.15.0 CPython cases fail; after the fix, all 44 added cases pass.
  • Added wildcard-CPE distro fallback controls (Debian, RPM, APK epochs and invalid versions) and unrelated vendor/product/part controls; unparseable PEP 440 versions keep the original package comparator.
  • Explicit CPE update fields retain their existing conservative comparison, with alpha/beta/RC controls preventing a prerelease from being treated as final.
  • go test ./grype/matcher/internal ./grype/version -count=1 passes.
  • An identical locally assembled CPython 3.15.0 APK runtime scanned with an unchanged vulnerability database changes from one false-positive CVE match to zero matches and zero ignored matches.

Checklist

  • Added regression coverage.
  • DCO sign-off included.
  • No suppression or metadata changes.

Signed-off-by: Barak Stout <barakstout@gmail.com>
Signed-off-by: Barak Stout <barakstout@gmail.com>
Signed-off-by: Barak Stout <barakstout@gmail.com>
@BarakStout

Copy link
Copy Markdown
Author

Independent review at 3d933164438d33700c71329e57059dabd7b035e3: no actionable findings in the scoped CPython comparison change.

Reviewed the product/vendor/part and explicit-update guards, PEP 440 validation before overriding ecosystem comparison, and distro/wildcard fallback cases. Non-Python and OpenSSL letter-version behavior remains unchanged. Independently ran go test ./grype/matcher/internal ./grype/version; both suites pass. Tests retain vulnerable alpha-boundary matches while correctly excluding fixed alpha/beta/RC/final releases, and preserve conservative matching for unparseable or explicitly updated CPEs.

The change corrects version ordering; it does not change vulnerability data, package metadata, or suppression policy.

@BarakStout
BarakStout marked this pull request as ready for review October 9, 2026 15:47
jkreileder added a commit to jkreileder/cf-ips-to-hcloud-fw that referenced this pull request Oct 14, 2026
Move the builder and final images to python:3.15.0 (trixie and
alpine3.24) and the astral/uv tool images to 0.13.1-python3.15. All
pins were checked against the registry with crane.

Python 3.15.0 carries the fixes for CVE-2026-87910 (tarfile,
python/cpython#157309), CVE-2025-15367 (poplib, #143924) and
CVE-2026-12345 (tempfile, #158431), so their .grype.yaml entries go.

Grype still reports CVE-2025-15367 against 3.15.0: NVD's bound is
< 3.15.0a6 and grype's generic version ordering ranks the 3.15.0 final
before that alpha. Keep a single ignore for it, scoped to python
3.15.0, until CI's grype includes anchore/grype#3776.

Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
@mabneyEAT

Copy link
Copy Markdown

Additional public reproduction supporting this CPython version-ordering fix: Grype v0.121.0 still reports CVE-2025-15367 for stable upstream CPython 3.15.0 through the direct-CPE/stock-matcher path, with no distribution package or vendor backport involved.

docker run --rm anchore/grype:v0.121.0@sha256:621d56d1d68106b787022c81546f7e0a36202a25d1239f0c20195fab8c16f7ea \
  'cpe:2.3:a:python:python:3.15.0:*:*:*:*:*:*:*' -o json

Observed match:

  • artifact name/version: python / 3.15.0
  • namespace: nvd:cpe; matcher: stock-matcher; match type: cpe-match
  • constraint: < 3.15.0a6 (unknown); listed fixed version: 3.15.0a6
  • database v6.1.10 built 2026-10-19T06:39:15Z

Stable 3.15.0 is newer than alpha 6 under Python ordering. The public official python:3.15.0-alpine3.23 image also rejects a POP3 command containing CRLF before socket access. This supports adding/retaining a direct-CPE stock-matcher integration regression in addition to the binary/APK cases in this PR.

The same CPE-only scan also returns two Bitnami-namespace matches; those have separate advisory/product-applicability concerns and are not attributed to this comparator fix.

This branch has not been deployed

No deployments
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.

2 participants