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

Dashboard Data - Last 10 SBOMs Barchart #952

Open
carlosthe19916 opened this issue Oct 30, 2024 · 5 comments
Open

Dashboard Data - Last 10 SBOMs Barchart #952

carlosthe19916 opened this issue Oct 30, 2024 · 5 comments
Assignees
Labels
UI-V1 parity Tasks needed to get done for V1 UI parity

Comments

@carlosthe19916
Copy link
Member

The image below is how V1 looks like in regards of the Dashboard. In the left center part there is BarChart that renders the last 10 SBOMs ingested in the system. Each bar renders the number of vulnerabilities that each SBOM has

image-2024-10-23-11-43-39-294

Here are some things I'd like to have (we can separate each task on its own issue if that works too):

  • How to get the last 10 SBOMs "Ingested"? Currently I can sort SBOMs by published but as far as I understand that will sort by the date in which the SBOM was published which does not necessarily match the date in which it has been ingested into the system.
    • So I can not use /api/v1/sbom?sort=published:asc I need something else.
  • How to get Vulnerabilities for all 10 SBOMs?
    • Here is the problem I have: If the UI wants to determine vulnerabilities for those 10 SBOMs then I would need to follow these steps:
    • First: Get the last SBOMs with something like /api/v1/sbom?limit=10&offset=0&sort=published:asc
    • Second: For each SBOM fetch the advisories available using /api/v1/sbom/{id}/advisory. So this endpoint is called 10 times. This endpoint returns a list of advisories associated to each SBOM; each advisory will have a list of Vulnerability IDs (it can be from 0 to hundreds)
    • Third. For each Vulnerability identified in the previous step I need to fetch the vulnerability itself to know its severify and appropriately group them and make sure it is able to be rendered in the BarChart. If we identified hundred of vulnerabilities in the previous step then we will call /api/v1/vulnerability/{id} hundred times.

The final math of calls for /api/v1/vulnerability/{id} will be = 10SBOM multiplied by #Advisories multiplied by #Vulnerabilities. This can easily explode from hundreds to thousands. This is not going to scale.

@carlosthe19916 carlosthe19916 added the UI-V1 parity Tasks needed to get done for V1 UI parity label Oct 30, 2024
@jcrossley3
Copy link
Contributor

More details here: https://issues.redhat.com/browse/TC-1130

@jcrossley3 jcrossley3 self-assigned this Nov 4, 2024
@jcrossley3 jcrossley3 moved this to In progress in Trustify Nov 4, 2024
@carlosthe19916
Copy link
Member Author

Originally taken from https://docs.google.com/document/d/1PDTyvNlbzofq3_WaVFTkZY9JfGV4gz0qjctXhcPYfdw/edit?tab=t.0#heading=h.ijubi174bpxp

The process for generating the count of vulnerabilities (what the UI current code has) for a single SBOM can be summarized as:

Requirement

Given an SBOM the final goal is to be able to count how many vulnerabilities it has classified by severity. For instance:

Severity Count
Critical number
High number
Medium number
Low number
None number

To generate the previous table some calculations can be done in the client/UI and others in the backend. We need to design and decide exactly which calculations are done on the client/UI side and which ones in the backend side.

Current implementation (what the UI has)

Given a single SBOM:

  • Fetch all advisories related to the SBOM /api/v1/sbom/{id}/advisory
    • It will return an ARRAY of Advisories.
    • Each Advisory contains an ARRAY status. Each element of the ARRAY status contains a vulnerability_id and status
[
 {
   "identifier": "Advisory1",
   "status": [
     {
       "vulnerability_id": "CVE-1",
       "status": "affected"
     },
     {
       "vulnerability_id": "CVE-2",
       "status": "not_affected"
     }
   ]
 },
 {
   "identifier": "Advisory2",
   "status": [
     {
       "vulnerability_id": "CVE-2",
       "status": "affected"
     },
     {
       "vulnerability_id": "CVE-3",
       "status": "fixed|known_not_affected"
     }
   ]
 }
]
  • Take the status field of all advisories and put them in a single array. E.g. The previous ARRAY (the one with black background) will become:
[
 {
   "vulnerability_id": "CVE-1",
   "status": "affected"
 },
 {
   "vulnerability_id": "CVE-2",
   "status": "not_affected"
 },
 {
   "vulnerability_id": "CVE-2",
   "status": "affected"
 },
 {
   "vulnerability_id": "CVE-3",
   "status": "fixed|known_not_affected"
 }
]
  • Remove all elements whose status is different from “affected”. So we end up with the following array.
[
 {
   "vulnerability_id": "CVE-1",
   "status": "affected"
 },
 {
   "vulnerability_id": "CVE-2",
   "status": "affected"
 }
]
  • To get the severity we need to fetch each Vulnerability /api/v1/vulnerability/{id}
    • We enrich the previous object to something like:
[
 {
   "vulnerability_id": "CVE-1",
   "status": "affected",
   "severity": "critical"
 },
 {
   "vulnerability_id": "CVE-2",
   "status": "affected",
   "severity": "critical"
 }
]
  • Finally we take the array and group them by severity and make the final calculation to get to the very initial table described at the section Requirement

@carlosthe19916
Copy link
Member Author

An update @jcrossley3

I could suggest tackling this in 2 steps:

  • First step: enrich the endpoint /api/v1/sbom/{id}/advisory for the response to include the whole vulnerability and not just the ID.

so instead of the current response:

[
 {
   "identifier": "Advisory1",
   "status": [
     {
       "vulnerability_id": "CVE-1",
       "status": "affected"
     },
     {
       "vulnerability_id": "CVE-2",
       "status": "not_affected"
     }
   ]
 },
 {
   "identifier": "Advisory2",
   "status": [
     {
       "vulnerability_id": "CVE-2",
       "status": "affected"
     },
     {
       "vulnerability_id": "CVE-3",
       "status": "fixed|known_not_affected"
     }
   ]
 }
]

to become:

[
 {
   "identifier": "Advisory1",
   "status": [
     {
       "vulnerability": {
// THE WHOLE VULNERABILITY OBJECT THAT COMES WITH /api/v1/vulnerability/{id}
       },
       "status": "affected"
     },
     {
       "vulnerability": {
// THE WHOLE VULNERABILITY OBJECT THAT COMES WITH /api/v1/vulnerability/{id}
       },
       "status": "not_affected"
     }
   ]
 },
 {
   "identifier": "Advisory2",
   "status": [
     {
       "vulnerability": {
// THE WHOLE VULNERABILITY OBJECT THAT COMES WITH /api/v1/vulnerability/{id}
       },
       "status": "affected"
     },
     {
       "vulnerability": {
// THE WHOLE VULNERABILITY OBJECT THAT COMES WITH /api/v1/vulnerability/{id}
       },
       "status": "fixed|known_not_affected"
     }
   ]
 }
]
  • And the seconds step or phase could be to think how to make the logic/algorithm for handling multiple advisory's opinions in the backend.

The first step would allow me to move the dashboard on the UI while still applying the logic for dealing with multiple advisories in the UI. But we could have some to have things moving :)

@dejanb
Copy link
Contributor

dejanb commented Nov 14, 2024

So I tried in #1005 to implement this, but I think it will just make things worse. As VulnerabilityDetails will try to fetch and return a lot of unnecessary data.

The call like

http GET http://localhost:8080/api/v1/sbom/urn%3Auuid%3A019325b4-e588-72b2-9bcb-b75db98372bf/advisory

is now super-slow for me.

I think we would ideally return VulnerabilitySummary here, but that needs a bit more changes to fetch for a single vulnerability

@carlosthe19916
Copy link
Member Author

@dejanb thanks I agree with you, I tested your PR and I got the same experience. I ignore the internals of the backend but what you are suggesting seems very reasonable, to use VulnerabilitySummary to avoid unnecessary data and not to make the request very slow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
UI-V1 parity Tasks needed to get done for V1 UI parity
Projects
Status: In progress
Development

No branches or pull requests

3 participants