Skip to content

SC4 (OSV known vulnerable dependency) reports all historical CVEs when requirements.txt uses >= operator #42 #43

Description

@woxinsj

Summary

When requirements.txt uses >= (e.g. numpy>=1.26.0), SC4 ignores the bound and reports all historical CVEs for that package, not just the ones affecting the bound version. The bound can be raised above the CVE-fixed release and the scanner still reports every old CVE.

Environment

  • SkillSpector 2.1.3
  • Scan command: skillspector scan <path> --no-llm --format json
  • Target: requirements.txt (PEP 508 style)

Repro

Create a requirements.txt:

numpy>=1.26.0
Pillow>=10.4.0
scikit-learn>=1.5.0
httpx>=0.27.0

All four bounds are above the fixed versions of the CVEs the scanner reports.

Run:

skillspector scan .

Observed: 4× CRITICAL findings, each listing 2–10 historical CVEs that the bound should exclude.

Root cause

src/skillspector/nodes/analyzers/static_patterns_supply_chain.py lines 396–399:

m = re.match(r"^([a-zA-Z][a-zA-Z0-9._-]*)(?:\[.*?\])?\s*(?:([=<>!~]=?)\s*([\d.*]+))?", line)
if m:
    name = m.group(1)
    version = m.group(3) if m.group(2) in ("==", "<=") else None
    results.append((name, version, i))

version is set to None for any operator other than == / <=. The None propagates to the OSV query, which then returns every advisory ever filed for the package, instead of the subset that applies to the bound.

Expected

For numpy>=1.26.0, the scanner should either:

  • Query OSV with version=1.26.0 and return only CVEs affecting that version, or
  • Use a proper PEP 508 parser (e.g. packaging.requirements.Requirement) to extract the lowest acceptable version and filter CVEs against the affected range.

Suggested fix

  1. Replace the ad-hoc regex with packaging.requirements.Requirement(line).specifier.
  2. Pick the lowest valid version (e.g. >=1.26.01.26.0) and query OSV with that version.
  3. Filter returned CVEs to those whose affected range intersects the specifier's accepted set.
  4. (Optional) Add an inline-skip syntax (e.g. # skillspector: ignore=SC4 reason=...) so users can whitelist known false positives.

Workaround

In our project we upgraded all >= bounds to versions clearly above the CVE-fixed releases and accepted the scanner noise as informational. The bound values are correct at install time; only the scanner output is wrong.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions