Skip to content

Latest commit

 

History

History
150 lines (110 loc) · 5.55 KB

File metadata and controls

150 lines (110 loc) · 5.55 KB

Scanning Implementation

This article explains how to implement vulnerability scanning support for Chainguard Libraries in your scanner. This guide assumes your scanner already has the capability to detect language ecosystem packages (only Python currently) and match them to vulnerabilities using existing databases like NVD, GitHub Advisory Database, or OSV. This guide focuses on how to integrate Chainguard's VEX feed to correctly handle remediated packages.

Note: This article assumes you're already familiar with the material covered in Foundational Concepts.

Overview

To support Chainguard Libraries, your scanner needs to:

  1. Detect library packages using your existing detection methods
  2. Fetch VEX data from Chainguard's VEX feed
  3. Apply VEX statements to suppress vulnerabilities that have been fixed in remediated versions

The integration primarily involves consuming Chainguard's VEX feed and applying the VEX statements to your scan results.

Detecting Library Packages

Use your scanner's existing methods to detect library packages. The key requirement is preserving the full version string including local version identifiers:

  • Python: werkzeug==3.0.2+cgr.0 (the +cgr.0 suffix is critical)

Important: Remediated packages use local version identifiers (e.g., +cgr.0) to distinguish them from upstream versions. Your scanner must preserve these identifiers to correctly match VEX statements. The version identifier can be accessed from a lock file and/or after the dependency resolution step for ingestion.

When scanning declared dependencies (like requirements.txt), be aware that the declared version may differ from the actually installed version. For best results, scan the installed environment (Python virtual environments) rather than just lock files.

Consuming the VEX Feed

🎯 Goal: Apply VEX statements from Chainguard's feed to suppress false positives for remediated vulnerabilities.

VEX Feed Structure

Chainguard's VEX feed is compatible with the vex-repo-spec and follows the OpenVEX v0.2.0 specification.

Base URL: https://libraries.cgr.dev/openvex/v1/

Index file: https://libraries.cgr.dev/openvex/v1/index.json

The index file lists all available packages with their modification timestamps:

{
  "packages": [
    {
      "id": "pkg:pypi/werkzeug",
      "location": "pypi/werkzeug.openvex.json",
      "modified": "2025-10-23T06:01:33.081Z"
    },
    {
      "id": "pkg:pypi/pillow",
      "location": "pypi/pillow.openvex.json",
      "modified": "2025-10-23T06:01:32.44Z"
    }
  ]
}

Individual package files: https://libraries.cgr.dev/openvex/v1/<ecosystem>/<package_name>.openvex.json

For packages with namespaces: https://libraries.cgr.dev/openvex/v1/<ecosystem>/<namespace>/<package_name>.openvex.json

Examples:

  • https://libraries.cgr.dev/openvex/v1/pypi/werkzeug.openvex.json

VEX File Format

Each VEX file follows the OpenVEX v0.2.0 specification. As an exmple:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://openvex.dev/docs/public/vex-...",
  "author": "Chainguard Team",
  "supplier": "Chainguard",
  "statements": [
    {
      "vulnerability": {
        "name": "CGA-p5p5-4cg9-7w3c",
        "aliases": [
          "CVE-2024-34069",
          "GHSA-xg8h-j46f-w952"
        ]
      },
      "products": [
        {
          "identifiers": {
            "purl": "pkg:pypi/werkzeug@3.0.2%2Bcgr.1"
          }
        }
      ],
      "status": "fixed",
      "timestamp": "2025-10-23T06:01:32.44Z"
    }
  ]
}

Implementation Steps

After detecting packages using your scanner's existing methods, apply VEX data:

  1. For each detected package, construct its PURL (Package URL):

    • Format: pkg:<ecosystem>/<package_name>@<version>
    • Example: pkg:pypi/werkzeug@3.0.2%2Bcgr.0
  2. Fetch the VEX file for the package:

    • URL: https://libraries.cgr.dev/openvex/v1/<ecosystem>/<package_name>.openvex.json
    • Optionally use index.json to track modified timestamps for cache invalidation
  3. Process VEX statements:

    • Find statements where products[].identifiers.purl matches your package PURL
    • Extract the vulnerability information and status
  4. Apply VEX status to your scan results:

    • "fixed": Suppress this vulnerability. This is the only status Chainguard currently uses for remediated vulnerabilities.
  5. Map vulnerability identifiers:

    • Use vulnerability.aliases to map to CVE/GHSA IDs
    • Report using standard identifiers familiar to users

Example Workflow

Detected package: werkzeug==3.0.2+cgr.0

  1. Construct PURL: pkg:pypi/werkzeug@3.0.2%2Bcgr.0

  2. Fetch VEX file: GET https://libraries.cgr.dev/openvex/v1/pypi/werkzeug.openvex.json

  3. Parse VEX statement:

{
  "vulnerability": {
    "name": "CGA-2g68-c3qc-8985",
    "aliases": ["CVE-2024-34069", "GHSA-2g68-c3qc-8985"]
  },
  "products": [
    {"identifiers": {"purl": "pkg:pypi/werkzeug@3.0.2%2Bcgr.0"}}
  ],
  "status": "fixed"
}
  1. Apply result: Suppress CVE-2024-34069 from scan results for this package

Additional Resources