diff --git a/src/lib/singleview/components/ProductVulnerabilities.svelte b/src/lib/singleview/components/ProductVulnerabilities.svelte
index 014cc3a..2bacca4 100644
--- a/src/lib/singleview/components/ProductVulnerabilities.svelte
+++ b/src/lib/singleview/components/ProductVulnerabilities.svelte
@@ -10,17 +10,21 @@
-{#if $appStore.doc}
+{#if isDocumentASecurityAdvisory}
Vulnerabilities overview
{#if productLines.length > 0}
diff --git a/src/lib/singleview/docmodel/docmodel.ts b/src/lib/singleview/docmodel/docmodel.ts
index a098af8..fcea503 100644
--- a/src/lib/singleview/docmodel/docmodel.ts
+++ b/src/lib/singleview/docmodel/docmodel.ts
@@ -139,7 +139,7 @@ const convertToDocModel = (csafDoc: any): DocModel => {
trackingVersion: getTrackingVersion(csafDoc),
revisionHistory: [],
lastUpdate: getLastUpdate(csafDoc),
- vulnerabilities: [],
+ productVulnerabilities: [],
isDocPresent: checkDocumentPresent(csafDoc),
isTrackingPresent: checkTrackingPresent(csafDoc),
isDistributionPresent: checkDistributionPresent(csafDoc),
diff --git a/src/lib/singleview/docmodel/docmodeltypes.ts b/src/lib/singleview/docmodel/docmodeltypes.ts
index 8bafd3c..ce5cc35 100644
--- a/src/lib/singleview/docmodel/docmodeltypes.ts
+++ b/src/lib/singleview/docmodel/docmodeltypes.ts
@@ -48,6 +48,12 @@ export const Status = {
} as const;
export type StatusKeys = (typeof Status)[keyof typeof Status];
+export const DocumentCategory = {
+ CSAF_SECURITY_ADVISORY: "csaf_security_advisory",
+ CSAF_BASE: "csaf_base",
+ CSAF_VEX: "csaf_vex"
+} as const;
+
export type Publisher = {
category: string;
name: string;
@@ -73,7 +79,7 @@ export type DocModel = {
publisher: Publisher;
trackingVersion: string;
revisionHistory: RevisionHistoryEntry[];
- vulnerabilities: Array
>;
+ productVulnerabilities: Array>;
isDocPresent: boolean;
isTrackingPresent: boolean;
isDistributionPresent: boolean;
diff --git a/src/lib/singleview/productvulnerabilities/productvulnerabilities.test.ts b/src/lib/singleview/productvulnerabilities/productvulnerabilities.test.ts
index 995d01e..2e3663f 100644
--- a/src/lib/singleview/productvulnerabilities/productvulnerabilities.test.ts
+++ b/src/lib/singleview/productvulnerabilities/productvulnerabilities.test.ts
@@ -12,7 +12,7 @@ import {
extractVulnerabilities,
generateProductVulnerabilities
} from "./productvulnerabilities";
-import { ProductStatusSymbol } from "./productvulnerabilitiestypes";
+import { ProductStatusSymbol, type Vulnerability } from "./productvulnerabilitiestypes";
const emptyObject = {};
@@ -264,48 +264,48 @@ describe("Productvulnerabilities test", () => {
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses empty object", () => {
- const result = extractVulnerabilities(emptyObject);
- expect(result.length).toBe(0);
+ const { vulnerabilities } = extractVulnerabilities(emptyObject);
+ expect(vulnerabilities.length).toBe(0);
});
});
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses no vulnerabilities", () => {
- const result = extractVulnerabilities(noVulnerabilities);
- expect(result.length).toBe(0);
+ const { vulnerabilities } = extractVulnerabilities(noVulnerabilities);
+ expect(vulnerabilities.length).toBe(0);
});
});
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses vulnerability without cve", () => {
- const result = extractVulnerabilities(vulnerability_wo_CVE);
- expect(result.length).toBe(1);
+ const { vulnerabilities } = extractVulnerabilities(vulnerability_wo_CVE);
+ expect(vulnerabilities.length).toBe(0);
});
});
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses vulnerability with empty product_status", () => {
- const result = extractVulnerabilities(vulnerability_empty_product_status);
- expect(result.length).toBe(1);
+ const { vulnerabilities } = extractVulnerabilities(vulnerability_empty_product_status);
+ expect(vulnerabilities.length).toBe(1);
});
});
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses vulnerability with empty known_affected", () => {
- const result = extractVulnerabilities(vulnerability_known_affected_empty);
- expect(result.length).toBe(1);
- expect(Object.keys(result[0].known_affected).length).toBe(0);
+ const { vulnerabilities } = extractVulnerabilities(vulnerability_known_affected_empty);
+ expect(vulnerabilities.length).toBe(1);
+ expect(Object.keys(vulnerabilities[0].known_affected!).length).toBe(0);
});
});
describe("Productvulnerabilities test", () => {
it("Vulnerability: parses vulnerability with filled known_affected", () => {
- const result = extractVulnerabilities(vulnerability_known_affected_filled);
- const value = result[0];
- expect(result.length).toBe(1);
- expect(Object.keys(value.known_affected).length).toBe(2);
- expect(value.known_affected["123"]).toBe("123");
- expect(value.known_affected["456"]).toBe("456");
+ const { vulnerabilities } = extractVulnerabilities(vulnerability_known_affected_filled);
+ const value = vulnerabilities[0];
+ expect(vulnerabilities.length).toBe(1);
+ expect(Object.keys(value.known_affected!).length).toBe(2);
+ expect(value.known_affected!["123"]).toBe("123");
+ expect(value.known_affected!["456"]).toBe("456");
});
});
diff --git a/src/lib/singleview/productvulnerabilities/productvulnerabilities.ts b/src/lib/singleview/productvulnerabilities/productvulnerabilities.ts
index e8d2ad3..f41b5d1 100644
--- a/src/lib/singleview/productvulnerabilities/productvulnerabilities.ts
+++ b/src/lib/singleview/productvulnerabilities/productvulnerabilities.ts
@@ -12,12 +12,16 @@ import {
type Product,
type Relationship,
type ProductStatus_t,
- type ProductStatus_t_Key
+ type ProductStatus_t_Key,
+ type VulnerabilitesExtractionResult
} from "./productvulnerabilitiestypes";
const generateProductVulnerabilities = (jsonDocument: any) => {
- const products = extractProducts(jsonDocument);
- let vulnerabilities = extractVulnerabilities(jsonDocument);
+ let products = extractProducts(jsonDocument);
+ let { vulnerabilities, relevantProducts } = extractVulnerabilities(jsonDocument);
+ products = products.filter((product: Product) => {
+ return relevantProducts[product.product_id];
+ });
vulnerabilities.sort((vuln1: Vulnerability, vuln2: Vulnerability) => {
if (vuln1.cve < vuln2.cve) return -1;
if (vuln1.cve > vuln2.cve) return 1;
@@ -119,43 +123,57 @@ const generateDictFrom = (productStatus: ProductStatus_t, section: ProductStatus
}, {});
};
-const extractVulnerabilities = (jsonDocument: any): Vulnerability[] => {
+const extractVulnerabilities = (jsonDocument: any): VulnerabilitesExtractionResult => {
+ const extractionResult: VulnerabilitesExtractionResult = {
+ vulnerabilities: [],
+ relevantProducts: {}
+ };
if (!jsonDocument.vulnerabilities) {
- return [];
+ return extractionResult;
}
- return jsonDocument.vulnerabilities.reduce((acc: Vulnerability[], vulnerability: any) => {
- if (!vulnerability.cve) {
- return acc;
- }
- const result: Vulnerability = {
- cve: vulnerability.cve
- };
- if (vulnerability.product_status) {
- if (vulnerability.product_status.known_affected) {
- result.known_affected = generateDictFrom(vulnerability.product_status, "known_affected");
+ const vulnerabilities = jsonDocument.vulnerabilities.reduce(
+ (acc: Vulnerability[], vulnerability: any) => {
+ if (!vulnerability.cve) {
+ return acc;
}
- if (vulnerability.product_status.fixed) {
- result.fixed = generateDictFrom(vulnerability.product_status, "fixed");
+ const result: Vulnerability = {
+ cve: vulnerability.cve
+ };
+ if (vulnerability.product_status) {
+ if (vulnerability.product_status.known_affected) {
+ result.known_affected = generateDictFrom(vulnerability.product_status, "known_affected");
+ Object.assign(extractionResult.relevantProducts, result.known_affected);
+ }
+ if (vulnerability.product_status.fixed) {
+ result.fixed = generateDictFrom(vulnerability.product_status, "fixed");
+ Object.assign(extractionResult.relevantProducts, result.fixed);
+ }
+ if (vulnerability.product_status.under_investigation) {
+ result.under_investigation = generateDictFrom(
+ vulnerability.product_status,
+ "under_investigation"
+ );
+ Object.assign(extractionResult.relevantProducts, result.under_investigation);
+ }
+ if (vulnerability.product_status.known_not_affected) {
+ result.known_not_affected = generateDictFrom(
+ vulnerability.product_status,
+ "known_not_affected"
+ );
+ Object.assign(extractionResult.relevantProducts, result.known_not_affected);
+ }
+ if (vulnerability.product_status.recommended) {
+ result.recommended = generateDictFrom(vulnerability.product_status, "recommended");
+ Object.assign(extractionResult.relevantProducts, result.recommended);
+ }
}
- if (vulnerability.product_status.under_investigation) {
- result.under_investigation = generateDictFrom(
- vulnerability.product_status,
- "under_investigation"
- );
- }
- if (vulnerability.product_status.known_not_affected) {
- result.known_not_affected = generateDictFrom(
- vulnerability.product_status,
- "known_not_affected"
- );
- }
- if (vulnerability.product_status.recommended) {
- result.recommended = generateDictFrom(vulnerability.product_status, "recommended");
- }
- }
- acc.push(result);
- return acc;
- }, []);
+ acc.push(result);
+ return acc;
+ },
+ []
+ );
+ extractionResult.vulnerabilities = vulnerabilities;
+ return extractionResult;
};
export { extractProducts, extractVulnerabilities, generateProductVulnerabilities };
diff --git a/src/lib/singleview/productvulnerabilities/productvulnerabilitiestypes.ts b/src/lib/singleview/productvulnerabilities/productvulnerabilitiestypes.ts
index e542af4..3f0072a 100644
--- a/src/lib/singleview/productvulnerabilities/productvulnerabilitiestypes.ts
+++ b/src/lib/singleview/productvulnerabilities/productvulnerabilitiestypes.ts
@@ -59,3 +59,8 @@ export type Vulnerability = {
known_not_affected?: StringObject;
recommended?: StringObject;
};
+
+export type VulnerabilitesExtractionResult = {
+ vulnerabilities: Vulnerability[];
+ relevantProducts: StringObject;
+};