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

feat(redhat): migrate to CSAF VEX #7452

Open
knqyf263 opened this issue Sep 6, 2024 · 4 comments
Open

feat(redhat): migrate to CSAF VEX #7452

knqyf263 opened this issue Sep 6, 2024 · 4 comments
Milestone

Comments

@knqyf263
Copy link
Collaborator

knqyf263 commented Sep 6, 2024

Description

OVALv2 is in maintenance mode now.
https://www.redhat.com/en/blog/red-hat-vex-files-cves-are-now-generally-available

@knqyf263
Copy link
Collaborator Author

knqyf263 commented Sep 21, 2024

I summarized my understanding so far. It is probably missing something. I'll keep updating.

Flow chart

graph TD
    %% Node Definitions
    A([Start])
    B[Parse CSAF Document]
    C[Process '.document']
    D[Save '.aggregate_severity']
    E[Process '.vulnerabilities']
    F{More vulnerabilities?}
    G[Save '.cve' as CVE-ID]
    H[Process '.remediations']
    I{More remediations?}
    J{Category?}
    K[Extract RHSA-ID from '.url' and Save]
    L[Save '.details' as status and '.product_ids']
    M[Process '.threats']
    N{More threats?}
    O{Category?}
    P[Save '.details' as severity and '.product_ids']
    Q[Process '.product_status']
    R{Status?}
    S{More statuses?}
    T{More products in the status?}
    U{Is product_id in relationships?}
    V[Look up relationship from '.product_tree.relationships']
    W[Look up detailed status from '.remediations']
    X[Look up detailed severity from '.threats']
    Y{Is '.product_reference' in '.product_tree'?}
    Z{Is '.category' '.product_version'?}
    AA[Save component PURL]
    AB{Is '.relates_to_product_reference' in '.relationships'?}
    AC[Look up relationship from '.product_tree.relationships']
    AD{Is '.relates_to_product_reference' in '.product_tree'?}
    AE[Save product CPE]
    AF{Is it a modular package?}
    AG[Process as modular package]
    AH[Save '.product_reference' as module stream]
    AI[Aggregate collected information]
    ERR1([Error: Product not found in product_tree])
    ERR2([Error: Invalid category])
    ERR3([Error: Unexpected relationship])
    ERR4([Error: Product not found])
    END([End])

    %% Links
    A --> B
    B --> C
    C --> D
    C --> E
    E --> F
    F -->|Yes| G
    F -->|No| END
    G --> H
    H --> I
    I -->|Yes| J
    I -->|No| M
    J -->|vendor_fix| K
    J -->|no_fix_planned| L
    J -->|none_available| L
    J -->|other| I
    K --> I
    L --> I
    M --> N
    N -->|Yes| O
    N -->|No| Q
    O -->|impact| P
    O -->|other| N
    P --> N
    Q --> S
    S -->|Yes| R
    S -->|No| F
    R -->|known_affected| T
    R -->|other| S
    R -->|fixed| T
    T -->|Yes| U
    T -->|No| S
    U -->|Yes| V
    U -->|No: unsupported| T
    V --> Y
    V --> W
    W --> X
    Y -->|Yes| Z
    Y -->|No| ERR1
    Z -->|Yes| AA --> AI
    Z -->|No| ERR2
    V --> AB
    AB -->|Yes| AC
    AB -->|No| AD
    AC --> AF
    AD -->|Yes| AE --> AI
    AD -->|No| ERR4
    AF -->|Yes| AG
    AF -->|No| ERR3
    AG --> AH
    AG --> AD
    AH --> AI
    AI --> T
Loading

Walkthrough

Provides a general overview of the CSAF (Common Security Advisory Framework) document parsing process in Trivy, using a simplified example based on Red Hat's security data. Please note that this explanation is intended to give a broad understanding of the process and omits some technical details for clarity.

1. Parse CSAF Document

We begin by parsing the CSAF VEX (Vulnerability Exploitability eXchange) document. In this example, we're using the document from:

https://access.redhat.com/security/data/csaf/v2/vex/2022/cve-2022-40152.json

The parsing is done using the library from github.com/csaf-poc/csaf_distribution.

2. Process '.document'

2.1 Save '.aggregate_severity'

We extract and save the aggregate severity from the document metadata. In our example:

"document": {
    "aggregate_severity": {
        "namespace": "https://access.redhat.com/security/updates/classification/",
        "text": "moderate"
    },
    ...
}

We save the value "moderate" from .document.aggregate_severity.text.

3. Process '.vulnerabilities'

We iterate through the vulnerabilities in the document. For each vulnerability:

3.1 Save '.cve' as CVE-ID

We extract and save the CVE ID. In our example:

"vulnerabilities": [
  {
    "cve": "CVE-2022-40152",
    "cwe": {
      "id": "CWE-787",
      "name": "Out-of-bounds Write"
    },
  }

We save "CVE-2022-40152" from .vulnerabilities[].cve.

3.2 Process '.remediations'

We iterate through the remediations for each vulnerability:

3.2.1 For 'vendor_fix' category:

{
  "category": "vendor_fix",
  "details": "Before applying this update, make sure all previously released errata\nrelevant to your system have been applied.\n\nFor details on how to apply this update, refer to:\n\nhttps://access.redhat.com/articles/11258",
  "product_ids": [
    "RHINT Camel-Springboot 3.18.3.P2"
  ],
  "url": "https://access.redhat.com/errata/RHSA-2023:3641"
}

When .category == vendor_fix, we extract the RHSA-ID from the .url field.

3.2.2 For 'no_fix_planned' or 'none_available' categories:

{
  "category": "no_fix_planned",
  "details": "Will not fix",
  "product_ids": [
    "migration_toolkit_for_runtimes:xstream",
    "red_hat_data_grid_8:xstream",
    "red_hat_jboss_fuse_7:woodstox-core",
    "red_hat_satellite_6:woodstox-core"
  ]
}

We save the .details (e.g., "Will not fix") along with the .product_ids for products with known_affected status.

3.3 Process '.threats'

We iterate through the threats for each vulnerability:

{
  "category": "impact",
  "details": "Moderate",
  "product_ids": [
    "AppStream-8.8.0.GA:xorg-x11-server-0:1.20.11-15.el8.src",
    "AppStream-8.8.0.GA:xorg-x11-server-Xdmx-0:1.20.11-15.el8.aarch64",
    "AppStream-8.8.0.GA:xorg-x11-server-Xdmx-0:1.20.11-15.el8.ppc64le"
  ]
}  

When category == impact, we save the severity (e.g., "Moderate") along with the .product_ids, as this severity might differ from the overall .document.aggregate_severity.

3.4 Process '.product_status'

We iterate through the key/value pairs in .product_status, processing only 'fixed' and 'known_affected' statuses:

"product_status": {
  "fixed": [
    "7Server-JBEAP-7.4:eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch",
    "7Server-JBEAP-7.4:eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.src",
    ...
  ],
  ...
}

For each product ID:

  1. Look up the product ID in the relationships:

Look up the product ID (7Server-JBEAP-7.4:eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch) in .product_tree.relationships:

{
  "category": "default_component_of",
  "full_product_name": {
    "name": "eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch as a component of Red Hat JBoss EAP 7.4 for RHEL 7 Server",
    "product_id": "7Server-JBEAP-7.4:eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch"
  },
  "product_reference": "eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch",
  "relates_to_product_reference": "7Server-JBEAP-7.4"
}
  1. Resolve relates_to_product_reference in product tree

Resolve relates_to_product_reference (7Server-JBEAP-7.4) in .product_tree.branches[]:

{
  "category": "product_name",
  "name": "Red Hat JBoss EAP 7.4 for RHEL 7 Server",
  "product": {
    "name": "Red Hat JBoss EAP 7.4 for RHEL 7 Server",
    "product_id": "7Server-JBEAP-7.4",
    "product_identification_helper": {
      "cpe": "cpe:/a:redhat:jboss_enterprise_application_platform:7.4::el7"
    }
  }
}

If category == product_name, save the CPE (cpe:/a:redhat:jboss_enterprise_application_platform:7.4::el7).

  1. Resolve product_reference in product tree:

Resolve product_reference (eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch) in .product_tree.branches[]:

{
  "category": "product_version",
  "name": "eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch",
  "product": {
    "name": "eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch",
    "product_id": "eap7-woodstox-core-0:6.4.0-1.redhat_00001.1.el7eap.noarch",
    "product_identification_helper": {
      "purl": "pkg:rpm/redhat/[email protected]_00001.1.el7eap?arch=noarch"
    }
  }
}

If category == product_version, parse the PURL to extract the package name, version (for 'fixed' status), and architecture.

  1. For 'known_affected' status, retrieve the detailed status from remediations (e.g., "Will not fix").

  2. If applicable, retrieve the product-specific severity from threats.

After processing all product IDs for a status, move to the next status. After processing all statuses, move to the next vulnerability. The process ends when all vulnerabilities have been processed.

@DmitriyLewen
Copy link
Contributor

LGTM.

left a couple comments:

We iterate through the key/value pairs in .product_status, processing only 'fixed' and 'known_affected' statuses:

Perhaps we need to check other statuses (I haven't had time to check their availability yet) (see https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#3239-vulnerabilities-property---product-status)
But i think last_affected can be used.

Resolve relates_to_product_reference in product tree

Let's add that we use branches

@knqyf263
Copy link
Collaborator Author

Perhaps we need to check other statuses (I haven't had time to check their availability yet) (see https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#3239-vulnerabilities-property---product-status)

According to the announcement, they use only 4 statuses, but yes, I'll check the data.

A VEX file would be available, marking those products using one of the product status attributes: fixed, known_affected, known_not_affected, or under_investigation.

Let's add that we use branches

Updated

@knqyf263
Copy link
Collaborator Author

I confirmed they use only 4 status types.

map[first_affected:0 first_fixed:0 fixed:8023040 known_affected:63100 known_not_affected:1121477 last_affected:0 recommended:0 under_investigation:1867]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

2 participants