aquasecurity / trivy

Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more
https://aquasecurity.github.io/trivy
Apache License 2.0
22.91k stars 2.26k forks source link

bug(cyclonedx): Trivy image scan reports and counts the same CVE for the same package multiple times #5796

Closed DmitriyLewen closed 2 months ago

DmitriyLewen commented 9 months ago

Discussed in https://github.com/aquasecurity/trivy/discussions/5788

Originally posted by **LesSyner** December 15, 2023 ### Description Trivy sometimes reports the same CVE for te same package multiple times (in single scan) resulting in incorrect number of CVEs for image. ### Desired Behavior trivy should report the same CVE for the same package only once ### Actual Behavior trivy reports multiple CVEs when in fact it's single occurance. Here is an example: { "id": "CVE-2023-44981", "source": { "name": "ghsa", "url": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Amaven" }, "ratings": [ { "source": { "name": "bitnami" }, "score": 9.1, "severity": "critical", "method": "CVSSv31", "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N" }, { "source": { "name": "ghsa" }, "score": 9.1, "severity": "critical", "method": "CVSSv31", "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N" }, { "source": { "name": "nvd" }, "score": 9.1, "severity": "critical", "method": "CVSSv31", "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N" }, { "source": { "name": "redhat" }, "score": 9.1, "severity": "critical", "method": "CVSSv31", "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N" } ], "cwes": [ 639 ], "description": "Authorization Bypass Through User-Controlled Key vulnerability in Apache ZooKeeper. If SASL Quorum Peer authentication is enabled in ZooKeeper (quorum.auth.enableSasl=true), the authorization is done by verifying that the instance part in SASL authentication ID is listed in zoo.cfg server list. The instance part in SASL auth ID is optional and if it's missing, like 'eve@EXAMPLE.COM', the authorization check will be skipped. As a result an arbitrary endpoint could join the cluster and begin propagating counterfeit changes to the leader, essentially giving it complete read-write access to the data tree. Quorum Peer authentication is not enabled by default.\n\nUsers are recommended to upgrade to version 3.9.1, 3.8.3, 3.7.2, which fixes the issue.\n\nAlternately ensure the ensemble election/quorum communication is protected by a firewall as this will mitigate the issue.\n\nSee the documentation for more details on correct cluster administration.\n", "recommendation": "Upgrade org.apache.zookeeper:zookeeper to version 3.7.2, 3.8.3, 3.9.1", "advisories": [ { "url": "https://avd.aquasec.com/nvd/cve-2023-44981" }, { "url": "http://www.openwall.com/lists/oss-security/2023/10/11/4" }, { "url": "https://access.redhat.com/security/cve/CVE-2023-44981" }, { "url": "https://github.com/apache/zookeeper" }, { "url": "https://lists.apache.org/thread/wf0yrk84dg1942z1o74kd8nycg6pgm5b" }, { "url": "https://lists.debian.org/debian-lts-announce/2023/10/msg00029.html" }, { "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-44981" }, { "url": "https://www.cve.org/CVERecord?id=CVE-2023-44981" }, { "url": "https://www.debian.org/security/2023/dsa-5544" } ], "published": "2023-10-11T12:15:00+00:00", "updated": "2023-11-01T07:15:00+00:00", "affects": [ { "ref": "pkg:maven/org.apache.zookeeper/zookeeper@3.6.3?file_path=usr%2Fshare%2Fjava%2Fconfluent-control-center%2Fzookeeper-3.6.3.jar", "versions": [ { "version": "3.6.3", "status": "affected" } ] }, { "ref": "pkg:maven/org.apache.zookeeper/zookeeper@3.6.3?file_path=usr%2Fshare%2Fjava%2Fconfluent-control-center%2Fzookeeper-3.6.3.jar", "versions": [ { "version": "3.6.3", "status": "affected" } ] }, { "ref": "pkg:maven/org.apache.zookeeper/zookeeper@3.6.3?file_path=usr%2Fshare%2Fjava%2Fconfluent-control-center%2Fzookeeper-3.6.3.jar", "versions": [ { "version": "3.6.3", "status": "affected" } ] }, { "ref": "pkg:maven/org.apache.zookeeper/zookeeper@3.6.3?file_path=usr%2Fshare%2Fjava%2Fconfluent-control-center%2Fzookeeper-3.6.3.jar", "versions": [ { "version": "3.6.3", "status": "affected" } ] }, { "ref": "pkg:maven/org.apache.zookeeper/zookeeper@3.6.3?file_path=usr%2Fshare%2Fjava%2Fconfluent-control-center%2Fzookeeper-3.6.3.jar", "versions": [ { "version": "3.6.3", "status": "affected" } ] } ] }, ### Reproduction Steps ```bash 1. trivy image --ignore-unfixed confluentinc/cp-schema-registry:7.5.2 --scanners vuln --severity CRITICAL -f cyclonedx ``` ### Target Container Image ### Scanner Vulnerability ### Output Format CycloneDX ### Mode Standalone ### Debug Output ```bash 2023-12-15T10:36:47.504+0100 DEBUG ["cyclonedx" "spdx" "spdx-json" "github"] automatically enables '--list-all-pkgs'. 2023-12-15T10:36:47.505+0100 DEBUG Severities: ["CRITICAL"] 2023-12-15T10:36:47.506+0100 DEBUG Ignore statuses {"statuses": ["unknown","not_affected","affected","under_investigation","will_not_fix","fix_deferred","end_of_life"]} 2023-12-15T10:36:47.523+0100 DEBUG cache dir: /Users/test/Library/Caches/trivy 2023-12-15T10:36:47.523+0100 DEBUG DB update was skipped because the local DB is the latest 2023-12-15T10:36:47.523+0100 DEBUG DB Schema: 2, UpdatedAt: 2023-12-15 06:10:50.163004975 +0000 UTC, NextUpdate: 2023-12-15 12:10:50.163004594 +0000 UTC, DownloadedAt: 2023-12-15 09:18:37.448303 +0000 UTC 2023-12-15T10:36:47.524+0100 INFO Vulnerability scanning is enabled 2023-12-15T10:36:47.524+0100 DEBUG Vulnerability type: [os library] 2023-12-15T10:36:47.524+0100 DEBUG Enabling misconfiguration scanners: [azure-arm cloudformation dockerfile helm kubernetes terraform terraformplan] 2023-12-15T10:36:49.274+0100 DEBUG The nuget packages directory couldn't be found. License search disabled 2023-12-15T10:36:49.454+0100 DEBUG Image ID: sha256:9c75bce947731d3ed3fba8e9f3d4646b2d15c3036f6d9062c5c4dd275a5045cc 2023-12-15T10:36:49.454+0100 DEBUG Diff IDs: [sha256:1053d00b8e292c8a36bef630a0f4977b29da4e2fd60ac9425e0fcd1f7c1108d5 sha256:2784298e924345d0daf7eed5793662efbeb830bd3f83bc1bdf58dacf7a266477 sha256:e6074c53f57ac4a6c1163951950677943cf3608a3e79b400961eac20e44631d3 sha256:cf101d0177010a1169bd2c88481fa1086ee4eaf8f2433ccb431c657c3aa645e9 sha256:04394050f85b15adb4e989d29cbeaa2823aeec2928e1f17619a7fe83880ffcb7 sha256:f2f1f826c954809927a3684e569272533a951c885163b65efa2d021fb0d60759 sha256:9ab333f76a764635010e0f6872a40a21ce4f678a189689f2d6ec197d0880482f sha256:905c75c815e0a8cda612ef911e8a58eb3b34ed202f743cf847ced2850cd9bee7 sha256:d43f08d70ed9b8566f13578e2ab55a2697b7292dd1fccf107b28b007e877ca5a sha256:2b5c9ac251e65f3863a1c284b0b33bfc09deaf038f7d2a52997149b17daaf16e sha256:55d28c8a35a4f7d553aed857bba92f60f53bd38271d486166e6eb57e068e1871] 2023-12-15T10:36:49.454+0100 DEBUG Base Layers: [] 2023-12-15T10:36:49.575+0100 INFO Detected OS: redhat 2023-12-15T10:36:49.575+0100 INFO Detecting RHEL/CentOS vulnerabilities... 2023-12-15T10:36:49.575+0100 DEBUG Red Hat: os version: 8 2023-12-15T10:36:49.575+0100 DEBUG Red Hat: the number of packages: 188 2023-12-15T10:36:49.632+0100 INFO Number of language-specific files: 2 2023-12-15T10:36:49.632+0100 INFO Detecting python-pkg vulnerabilities... 2023-12-15T10:36:49.632+0100 DEBUG Detecting library vulnerabilities, type: python-pkg, path: 2023-12-15T10:36:49.635+0100 INFO Detecting jar vulnerabilities... 2023-12-15T10:36:49.635+0100 DEBUG Detecting library vulnerabilities, type: jar, path: 2023-12-15T10:36:49.691+0100 DEBUG Found an ignore file: .trivyignore ``` ### Operating System macOS Sonoma 14.2 ### Version ```bash Version: 0.48.0 Vulnerability DB: Version: 2 UpdatedAt: 2023-12-15 06:10:50.163004975 +0000 UTC NextUpdate: 2023-12-15 12:10:50.163004594 +0000 UTC DownloadedAt: 2023-12-15 09:18:37.448303 +0000 UTC Java DB: Version: 1 UpdatedAt: 2023-12-15 00:45:03.307690097 +0000 UTC NextUpdate: 2023-12-18 00:45:03.307689947 +0000 UTC DownloadedAt: 2023-12-15 09:19:43.769488 +0000 UTC ``` ### Checklist - [X] Run `trivy image --reset` - [X] Read [the troubleshooting](https://aquasecurity.github.io/trivy/latest/docs/references/troubleshooting/)
DmitriyLewen commented 9 months ago

Also there is problem with same jars in different folders. We create only 1 component: json report:

      "Packages": [
        {
          "Name": "com.fasterxml.jackson.core:jackson-databind",
          "Version": "2.13.4",
          "Layer": {},
          "FilePath": "1/jackson-databind-2.13.4.jar"
        },
        {
          "Name": "com.fasterxml.jackson.core:jackson-databind",
          "Version": "2.13.4",
          "Layer": {},
          "FilePath": "2/jackson-databind-2.13.4.jar"
        }
      ],

cyclonedx report:

  "components": [
    {
      "bom-ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4?file_path=2%2Fjackson-databind-2.13.4.jar",
      "type": "library",
      "group": "com.fasterxml.jackson.core",
      "name": "jackson-databind",
      "version": "2.13.4",
      "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4",
      "properties": [
        {
          "name": "aquasecurity:trivy:FilePath",
          "value": "2/jackson-databind-2.13.4.jar"
        },
        {
          "name": "aquasecurity:trivy:PkgType",
          "value": "jar"
        }
      ]
    }
  ],
LesSyner commented 9 months ago

Things look a bit different after further investigation:

  1. trivy with standard table output ( trivy image --ignore-unfixed confluentinc/cp-schema-registry:7.5.2 --scanners vuln --severity CRITICAL ) reports the same CVE (CVE-2023-44981) and with count 5 but now for 2 jars: org.apache.zookeeper:zookeeper (acl-7.5.2.jar) and org.apache.zookeeper:zookeeper (zookeeper-3.6.3.jar).
  2. I've extracted both jars from the image, unpacked them fully and checked that table report shows properly that there is zookeeper-3.6.3 also inside acl. So your remark @DmitriyLewen about ticket #5798 may be good direction. It's already somehow shown in tabe format but not in cyclonedx format.
  3. I've ran "trivy fs" with dir containing both jars unpacked, each in separate subdir, and it shows different results:
    • acl/META-INF/maven/org.apache.zookeeper/zookeeper with 1 critical CVE coming from org.apache.zookeeper:zookeeper 3.6.3 (the same CVE ID as reported in cyclonedx format)
    • zookeeper/META-INF/maven/org.apache.zookeeper/zookeeper with 1 critical CVE coming from org.apache.zookeeper:zookeeper 3.6.3 (the same CVE ID as reported in cyclonedx format)
    • acl/META-INF/maven/com.hubspot.jackson/jackson-datatype-protobuf with 12 critical CVEs coming from com.fasterxml.jackson.core:jackson-databind 2.9.9.

Now I'm confused - cyclonedx format reporting issues, table format partially ok (showing 2 separate files with this CVE), both formats don't show additional 12 critical CVEs (total 62 CVEs, both numbers with --ignore-unfixed switch).

DmitriyLewen commented 9 months ago

Hello @LesSyner Thanks for your investigation.

both formats don't show additional 12 critical CVEs

I am focusing on fixing CycloneDX logic. After that i will check this case.

DmitriyLewen commented 9 months ago

I checked acl-7.5.2.jar: When you scan in fs more - Trivy checks pom.xml files But when you scan in image (or rootfs) mode Trivy checks jar files (Trivy checks pom.properties, MANIFEST.MF and nested jars inside found jar) - https://aquasecurity.github.io/trivy/v0.48/docs/coverage/language/java/#jarwarparear

More about fs/image mode - https://aquasecurity.github.io/trivy/v0.48/docs/coverage/language/#supported-languages

For your case:

LesSyner commented 9 months ago

I digged deeper since so far there was no justification for 5 critical CVEs. And I've found them in report in json format. So in fact summary in all formats is ok (regarding 5 instances of CVE-2023-44981), only proper details are missing in table and cyclonedx format.

      "VulnerabilityID": "CVE-2023-44981",
      "PkgName": "org.apache.zookeeper:zookeeper",
      "PkgPath": "usr/share/java/acl/acl-7.5.2.jar",
      "InstalledVersion": "3.6.3",

      "VulnerabilityID": "CVE-2023-44981",
      "PkgName": "org.apache.zookeeper:zookeeper",
      "PkgPath": "usr/share/java/confluent-control-center/zookeeper-3.6.3.jar",
      "InstalledVersion": "3.6.3",

      "VulnerabilityID": "CVE-2023-44981",
      "PkgName": "org.apache.zookeeper:zookeeper",
      "PkgPath": "usr/share/java/confluent-security/connect/zookeeper-3.6.3.jar",
      "InstalledVersion": "3.6.3",

      "VulnerabilityID": "CVE-2023-44981",
      "PkgName": "org.apache.zookeeper:zookeeper",
      "PkgPath": "usr/share/java/cp-base-new/zookeeper-3.6.3.jar",
      "InstalledVersion": "3.6.3",

      "VulnerabilityID": "CVE-2023-44981",
      "PkgName": "org.apache.zookeeper:zookeeper",
      "PkgPath": "usr/share/java/schema-registry/zookeeper-3.6.3.jar",
      "InstalledVersion": "3.6.3",
DmitriyLewen commented 9 months ago

this problem is related with Applications aggregation. there is #4249 about table format.

topiga commented 4 months ago

I have the same problem. I made a very simple script that you can use to temporarily fix this issue. Here is the up-to-date gist : https://gist.github.com/topiga/4d459e6a922c2f08fec5a211975316fb Here is the code as of today, 25th April 2024

import json
import argparse

def remove_duplicates(json_data):
    for vulnerability in json_data['vulnerabilities']:
        affects = vulnerability['affects']
        unique_affects = []
        seen_refs = set()

        for affect in affects:
            ref = affect['ref']
            if ref not in seen_refs:
                seen_refs.add(ref)
                unique_affects.append(affect)

        vulnerability['affects'] = unique_affects

    return json_data

def main():
    parser = argparse.ArgumentParser(description='Fix CycloneDX file by removing duplicate items in the "affects" array.')
    parser.add_argument('--input', dest='input_file', required=True, help='Path to the input CycloneDX file')
    parser.add_argument('--output', dest='output_file', required=True, help='Path to the output fixed CycloneDX file')

    args = parser.parse_args()

    try:
        with open(args.input_file, 'r') as file:
            cyclonedx_data = json.load(file)
    except FileNotFoundError:
        print(f'Error: input file "{args.input_file}" not found')
        return
    except json.JSONDecodeError as e:
        print(f'Error: invalid JSON format in input file "{args.input_file}"')
        print(f'JSON error: {str(e)}')
        return

    updated_data = remove_duplicates(cyclonedx_data)

    try:
        with open(args.output_file, 'w') as file:
            json.dump(updated_data, file, indent=2)
    except IOError as e:
        print(f'Error: failed to write output file "{args.output_file}"')
        print(f'IO error: {str(e)}')
        return

    print(f'Fixed CycloneDX data written to "{args.output_file}"')

if __name__ == '__main__':
    main()
DmitriyLewen commented 4 months ago

Hello @topiga

Can you check this issue with latest Trivy? I think #6240 should fix this problem. e.g.:

Last login: Fri Apr 26 07:35:23 on ttys001
➜ tree ./dir 
./dir
├── dir1
│   └── jackson-databind-2.13.4.jar
└── dir2
    └── jackson-databind-2.13.4.jar

3 directories, 2 files
➜ trivy -q rootfs -f cyclonedx ./dir
{
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "serialNumber": "urn:uuid:45d8a637-d34b-4700-949d-911410f35c5a",
  "version": 1,
  "metadata": {
    "timestamp": "2024-04-26T01:45:03+00:00",
    "tools": {
      "components": [
        {
          "type": "application",
          "group": "aquasecurity",
          "name": "trivy",
          "version": "0.50.4"
        }
      ]
    },
    "component": {
      "bom-ref": "138052f2-ad09-4e00-824f-575c21306aaf",
      "type": "application",
      "name": "dir",
      "properties": [
        {
          "name": "aquasecurity:trivy:SchemaVersion",
          "value": "2"
        }
      ]
    }
  },
  "components": [
    {
      "bom-ref": "08210638-25c1-4d60-b4e6-2c59ed622f01",
      "type": "library",
      "group": "com.fasterxml.jackson.core",
      "name": "jackson-databind",
      "version": "2.13.4",
      "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4",
      "properties": [
        {
          "name": "aquasecurity:trivy:FilePath",
          "value": "dir2/jackson-databind-2.13.4.jar"
        },
        {
          "name": "aquasecurity:trivy:PkgType",
          "value": "jar"
        }
      ]
    },
    {
      "bom-ref": "5fb0bb40-d596-4e92-8597-5a1ccb4fa503",
      "type": "library",
      "group": "com.fasterxml.jackson.core",
      "name": "jackson-databind",
      "version": "2.13.4",
      "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4",
      "properties": [
        {
          "name": "aquasecurity:trivy:FilePath",
          "value": "dir1/jackson-databind-2.13.4.jar"
        },
        {
          "name": "aquasecurity:trivy:PkgType",
          "value": "jar"
        }
      ]
    }
  ],
  "dependencies": [
    {
      "ref": "08210638-25c1-4d60-b4e6-2c59ed622f01",
      "dependsOn": []
    },
    {
      "ref": "138052f2-ad09-4e00-824f-575c21306aaf",
      "dependsOn": [
        "08210638-25c1-4d60-b4e6-2c59ed622f01",
        "5fb0bb40-d596-4e92-8597-5a1ccb4fa503"
      ]
    },
    {
      "ref": "5fb0bb40-d596-4e92-8597-5a1ccb4fa503",
      "dependsOn": []
    }
  ],
  "vulnerabilities": []
}
sithmein commented 2 months ago

The problem still persists, also with the latest trivy version (0.52.2). In fact the CycloneDX file generated violates the schema (because of non-unique $.vulnerabilities[x].affects[*] which means that tools such as Dependency Track will reject the SBOM when being uploaded. To reproduce run trivy image -f cyclonedx -o ap.cdx.json --scanners license,vuln registry.hub.knime.com/knime/knime-full:r-5.2.0-271 and look for CVE-2014-125087.

DmitriyLewen commented 2 months ago

Hello @sithmein Thanks for information!

Created #7023 for your issue.

Regards, Dmitriy