Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matching java binary packages with NVD records is problematic #1718

Open
wagoodman opened this issue Feb 15, 2024 · 0 comments
Open

Matching java binary packages with NVD records is problematic #1718

wagoodman opened this issue Feb 15, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@wagoodman
Copy link
Contributor

Today we have a binary classifier in syft that raises up packages for particular instances of java binaries. On the vulnerability side of this, there are some qualities in the data that are not addressed:

These points are somewhat of a summary from other places:

The above issues lead to inconsistencies in matching. Take for example:

FROM alpine:latest as base
RUN apk add curl
RUN curl -o java.tar.gz https://cdn.azul.com/zulu/bin/zulu8.74.0.17-ca-jdk8.0.392-linux_x64.tar.gz
RUN tar -xzvf java.tar.gz

FROM scratch
COPY --from=base /zulu8.74.0.17-ca-jdk8.0.392-linux_x64/jre/bin/java /java
$ docker build -t localhost/jdk:latest .
$ syft localhost/jdk:latest -o json
{
  "id": "10fd53610ae246e3",
  "name": "java",
  "version": "1.8.0_392-b08",
  "type": "binary",
  "foundBy": "binary-cataloger",
  "locations": [
    {
      "path": "/java",
      "layerID": "sha256:dcd33fc5de2139e490023c1b6348c637fffbc7f9f45f0717738db6ac193a2418",
      "accessPath": "/java",
      "annotations": {
        "evidence": "primary"
      }
    }
  ],
  "licenses": [],
  "language": "",
  "cpes": [
    {
      "cpe": "cpe:2.3:a:oracle:openjdk:1.8.0_392-b08:*:*:*:*:*:*:*",
      "source": "syft-generated"
    },
    {
      "cpe": "cpe:2.3:a:java:java:1.8.0_392-b08:*:*:*:*:*:*:*",
      "source": "syft-generated"
    }
  ],
  "purl": "pkg:generic/java@1.8.0_392-b08",
  "metadataType": "binary-signature",
  "metadata": {
    "matches": [
      {
        "classifier": "java-binary-openjdk",
        "location": {
          "path": "/java",
          "layerID": "sha256:dcd33fc5de2139e490023c1b6348c637fffbc7f9f45f0717738db6ac193a2418",
          "accessPath": "/java",
          "annotations": {
            "evidence": "primary"
          }
        }
      }
    ]
  }
}
$ grype -q localhost/jdk:latest
NAME  INSTALLED      FIXED-IN  TYPE    VULNERABILITY   SEVERITY
java  1.8.0_392-b08            binary  CVE-2023-21930  High
java  1.8.0_392-b08            binary  CVE-2023-21967  Medium
java  1.8.0_392-b08            binary  CVE-2023-21954  Medium
java  1.8.0_392-b08            binary  CVE-2023-21939  Medium
java  1.8.0_392-b08            binary  CVE-2023-21938  Low
java  1.8.0_392-b08            binary  CVE-2023-21937  Low

...or more specifically in the JSON output for CVE-2023-21930:

{
  "vulnerability": {
    "id": "CVE-2023-21930",
    "dataSource": "https://nvd.nist.gov/vuln/detail/CVE-2023-21930",
    "namespace": "nvd:cpe",
    ...
  },
  "relatedVulnerabilities": [],
  "matchDetails": [
    {
      "type": "cpe-match",
      "matcher": "stock-matcher",
      "searchedBy": {
        "namespace": "nvd:cpe",
        "cpes": [
          "cpe:2.3:a:oracle:openjdk:1.8.0_392-b08:*:*:*:*:*:*:*"
        ],
        "Package": {
          "name": "java",
          "version": "1.8.0_392-b08"
        }
      },
      "found": {
        "vulnerabilityID": "CVE-2023-21930",
        "versionConstraint": "< 8 || >= 11, <= 11.0.18 || >= 17, <= 17.0.6 || = 8 || = 8-milestone1 || = 8-milestone2 || = 8-milestone3 || = 8-milestone4 || = 8-milestone5 || = 8-milestone6 || = 8-milestone7 || = 8-milestone8 || = 8-milestone9 || = 8-update101 || = 8-update102 || = 8-update11 || = 8-update111 || = 8-update112 || = 8-update121 || = 8-update131 || = 8-update141 || = 8-update151 || = 8-update152 || = 8-update161 || = 8-update162 || = 8-update171 || = 8-update172 || = 8-update181 || = 8-update191 || = 8-update192 || = 8-update20 || = 8-update201 || = 8-update202 || = 8-update211 || = 8-update212 || = 8-update221 || = 8-update222 || = 8-update231 || = 8-update232 || = 8-update241 || = 8-update242 || = 8-update25 || = 8-update252 || = 8-update262 || = 8-update271 || = 8-update281 || = 8-update282 || = 8-update291 || = 8-update301 || = 8-update302 || = 8-update31 || = 8-update312 || = 8-update322 || = 8-update332 || = 8-update342 || = 8-update352 || = 8-update362 || = 8-update40 || = 8-update45 || = 8-update5 || = 8-update51 || = 8-update60 || = 8-update65 || = 8-update66 || = 8-update71 || = 8-update72 || = 8-update73 || = 8-update74 || = 8-update77 || = 8-update91 || = 8-update92 || = 20 (unknown)",
        "cpes": [
          "cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*"
        ]
      }
    }
  ],
  "artifact": {
    "id": "10fd53610ae246e3",
    "name": "java",
    "version": "1.8.0_392-b08",
    "type": "binary",
    ...
  }
}

This is because there is a < 8 in the version constraint for all of these vulnerability records:

$ sqlite3 ./vulnerability.db 'SELECT id,namespace,package_name from vulnerability where package_name like "%jdk%" and namespace == "nvd:cpe" and version_constraint like "%< 8%" '
CVE-2023-21930|nvd:cpe|openjdk
CVE-2023-21937|nvd:cpe|openjdk
CVE-2023-21938|nvd:cpe|openjdk
CVE-2023-21939|nvd:cpe|openjdk
CVE-2023-21954|nvd:cpe|openjdk
CVE-2023-21967|nvd:cpe|openjdk

Say I had an SBOM where we had explictly a known bad version of openjdk:

$sqlite3 ./vulnerability.db 'SELECT id,namespace,package_name,version_constraint from vulnerability where package_name like "%jdk%" and namespace == "nvd:cpe" and version_constraint like "%= 1.8%" '
...
CVE-2022-21619|nvd:cpe|jdk|= 1.8.0-update341 || = 1.8.0-update345 || = 11.0.16.1 || = 17.0.4.1 || = 19
...
$ cat openjdk.1.8.0_352-b08.syft.json | jq '.artifacts[] | {name: .name, version: .version, cpes: .cpes, purl: .purl}'
{
  "name": "java",
  "version": "1.8.0_392-b08",
  "cpes": [
    {
      "cpe": "cpe:2.3:a:oracle:openjdk:1.8.0_392-b08:*:*:*:*:*:*:*",
      "source": "syft-generated"
    },
    {
      "cpe": "cpe:2.3:a:java:java:1.8.0_392-b08:*:*:*:*:*:*:*",
      "source": "syft-generated"
    }
  ],
  "purl": "pkg:generic/java@1.8.0_392-b08"
}

We wouldn't be able to match on it for a few reasons:

  1. based on what syft raises up, we will never surface anything that looks like <semver>-update<number>. Note that these versions are found in the artifact as <semver>_u?<update>-<build>?.

  2. we put in a package name of openjdk and not jdk

There are a few more entries in the DB for jdk than there are openjdk:

$ sqlite3 ./vulnerability.db 'SELECT id,namespace,package_name,version_constraint from vulnerability where package_name like "%openjdk%" and namespace == "nvd:cpe"' |
wc -l
      99

$ sqlite3 ./vulnerability.db 'SELECT id,namespace,package_name,version_constraint from vulnerability where package_name like "%jdk%" and namespace == "nvd:cpe"' | wc -l
    1302

This points to some tangible actions we could take:

  • in syft, start listing a CPE with jdk as well as openjdk
  • in vunnel, the NVD provider, change openjdk version constraints within node configurations to be based on the version number of the application and not the product number for all versions <9 (e.g. swap 8 update40 for 1.8 upadate 40)
  • update grype-db where we deal with placing update version info (e.g. -update40) to consider ecosystem specific changes when there are oracle:openjdk or oracle:jdk entires found. These should be written as _40 instead of -update40.
@wagoodman wagoodman added the bug Something isn't working label Feb 15, 2024
@willmurphyscode willmurphyscode self-assigned this Feb 16, 2024
@willmurphyscode willmurphyscode removed their assignment Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: In Progress
Development

No branches or pull requests

2 participants