diff --git a/public/locales/gsa-de.json b/public/locales/gsa-de.json
index 0d2498e56c..63e98a4f62 100644
--- a/public/locales/gsa-de.json
+++ b/public/locales/gsa-de.json
@@ -204,6 +204,7 @@
"CVE Filter": "CVE-Filter",
"CVE List": "CVE-Liste",
"CVE Scanner": "CVE-Scanner",
+ "CVE Severity": "CVE-Schweregrad",
"CVE: {{name}}": "CVE: {{name}}",
"CVEs": "CVEs",
"CVEs by CVSS (Total: {{count}})": "CVEs nach CVSS (Gesamt: {{count}})",
@@ -487,6 +488,11 @@
"Duration of last Scan": "Dauer des letzten Scans",
"Dynamic": "Dynamisch",
"Dynamic Severity": "Dynamischer Schweregrad",
+ "EPSS": "EPSS",
+ "EPSS Percentile": "EPSS-Perzentil",
+ "EPSS Score": "EPSS-Score",
+ "EPSS (CVE with highest severity)": "EPSS (CVE mit höchstem Schweregrad)",
+ "EPSS (highest EPSS score)": "EPSS (Höchster EPSS-Score)",
"ESXi": "ESXi",
"ESXi Credential": "ESXi-Anmeldedaten",
"ESXi authentication was successful": "ESXi-Authentifizierung war erfolgreich",
@@ -1133,6 +1139,7 @@
"Password only": "Nur Passwort",
"Password: Use existing Password": "Passwort: Verwende bestehendes Passwort",
"Path": "Pfad",
+ "Percentile": "Perzentil",
"Performance": "Leistungsdaten",
"Period": "Zeitintervall",
"Permission": "Berechtigung",
@@ -1403,6 +1410,7 @@
"Schedules Filter": "Zeitpläne-Filter",
"Schedules List": "Zeitplanliste",
"Scope": "Reichweite",
+ "Score": "Score",
"Scoring": "Scoring",
"Search by content": "Suche nach Inhalt",
"SecInfo": "Sicherheitsinfos",
diff --git a/src/web/pages/cves/filterdialog.jsx b/src/web/pages/cves/filterdialog.jsx
index 24b89fc168..9de784482f 100644
--- a/src/web/pages/cves/filterdialog.jsx
+++ b/src/web/pages/cves/filterdialog.jsx
@@ -56,6 +56,14 @@ const SORT_FIELDS = [
name: 'severity',
displayName: _l('Severity'),
},
+ {
+ name: 'epss_score',
+ displayName: _l('EPSS Score'),
+ },
+ {
+ name: 'epss_percentile',
+ displayName: _l('EPSS Percentile'),
+ },
];
export default createFilterDialog({
diff --git a/src/web/pages/cves/table.jsx b/src/web/pages/cves/table.jsx
index 3bcce860a0..d19695baf9 100644
--- a/src/web/pages/cves/table.jsx
+++ b/src/web/pages/cves/table.jsx
@@ -91,7 +91,7 @@ const Header = ({
title={_('Severity')}
/>
- {"EPSS"}
+ {_("EPSS")}
{isDefined(actionsColumn) ? (
actionsColumn
diff --git a/src/web/pages/nvts/__tests__/detailspage.jsx b/src/web/pages/nvts/__tests__/detailspage.jsx
index bf4af8d931..d99519502c 100644
--- a/src/web/pages/nvts/__tests__/detailspage.jsx
+++ b/src/web/pages/nvts/__tests__/detailspage.jsx
@@ -67,6 +67,23 @@ const nvt = NVT.fromElement({
_type: 'VendorFix',
__text: 'This is a description',
},
+ epss: {
+ max_severity: {
+ score: 0.8765,
+ percentile: 0.9,
+ cve: {
+ _id: 'CVE-2020-1234',
+ severity: 10.0,
+ },
+ },
+ max_epss: {
+ score: 0.9876,
+ percentile: 0.8,
+ cve: {
+ _id: 'CVE-2020-5678',
+ },
+ },
+ },
timeout: '',
refs: {
ref: [
@@ -308,6 +325,14 @@ describe('Nvt Detailspage tests', () => {
expect(element).toHaveTextContent('CVSS Origin');
expect(element).toHaveTextContent('N/A');
+ expect(element).toHaveTextContent('EPSS (CVE with highest severity)');
+ expect(element).toHaveTextContent('EPSS Score');
+ expect(element).toHaveTextContent('0.87650');
+ expect(element).toHaveTextContent('EPSS Percentile');
+ expect(element).toHaveTextContent('0.90000');
+ expect(element).toHaveTextContent('EPSS (highest EPSS score)');
+ expect(element).toHaveTextContent('0.98760');
+
expect(element).toHaveTextContent('Insight');
expect(element).toHaveTextContent('Foo');
diff --git a/src/web/pages/nvts/__tests__/listpage.jsx b/src/web/pages/nvts/__tests__/listpage.jsx
index 51c6f978c9..596e206220 100644
--- a/src/web/pages/nvts/__tests__/listpage.jsx
+++ b/src/web/pages/nvts/__tests__/listpage.jsx
@@ -45,6 +45,23 @@ const nvt = NVT.fromElement({
_type: 'VendorFix',
__text: 'This is a description',
},
+ epss: {
+ max_severity: {
+ score: 0.8765,
+ percentile: 0.9,
+ cve: {
+ _id: 'CVE-2020-1234',
+ severity: 10.0,
+ },
+ },
+ max_epss: {
+ score: 0.9876,
+ percentile: 0.8,
+ cve: {
+ _id: 'CVE-2020-5678',
+ },
+ },
+ },
refs: {
ref: [
{_type: 'cve', _id: 'CVE-2020-1234'},
@@ -192,16 +209,21 @@ describe('NvtsPage tests', () => {
expect(header[4]).toHaveTextContent('CVE');
expect(header[6]).toHaveTextContent('Severity');
expect(header[7]).toHaveTextContent('QoD');
+ expect(header[8]).toHaveTextContent('EPSS');
+ expect(header[9]).toHaveTextContent('Score');
+ expect(header[10]).toHaveTextContent('Percentile');
const row = baseElement.querySelectorAll('tr');
- expect(row[1]).toHaveTextContent('foo');
- expect(row[1]).toHaveTextContent('bar');
- expect(row[1]).toHaveTextContent('Mon, Jun 24, 2019 1:55 PM CEST');
- expect(row[1]).toHaveTextContent('Mon, Jun 24, 2019 12:12 PM CEST');
- expect(row[1]).toHaveTextContent('CVE-2020-1234');
- expect(row[1]).toHaveTextContent('CVE-2020-5678');
- expect(row[1]).toHaveTextContent('80 %');
+ expect(row[2]).toHaveTextContent('foo');
+ expect(row[2]).toHaveTextContent('bar');
+ expect(row[2]).toHaveTextContent('Mon, Jun 24, 2019 1:55 PM CEST');
+ expect(row[2]).toHaveTextContent('Mon, Jun 24, 2019 12:12 PM CEST');
+ expect(row[2]).toHaveTextContent('CVE-2020-1234');
+ expect(row[2]).toHaveTextContent('CVE-2020-5678');
+ expect(row[2]).toHaveTextContent('80 %');
+ expect(row[2]).toHaveTextContent('0.87650');
+ expect(row[2]).toHaveTextContent('0.90000');
});
test('should allow to bulk action on page contents', async () => {
diff --git a/src/web/pages/nvts/__tests__/row.jsx b/src/web/pages/nvts/__tests__/row.jsx
index febff4333a..75be014716 100644
--- a/src/web/pages/nvts/__tests__/row.jsx
+++ b/src/web/pages/nvts/__tests__/row.jsx
@@ -48,6 +48,23 @@ const entity = NVT.fromElement({
_type: 'VendorFix',
__text: 'This is a description',
},
+ epss: {
+ max_severity: {
+ score: 0.8765,
+ percentile: 0.9,
+ cve: {
+ _id: 'CVE-2020-1234',
+ severity: 10.0,
+ },
+ },
+ max_epss: {
+ score: 0.9876,
+ percentile: 0.8,
+ cve: {
+ _id: 'CVE-2020-5678',
+ },
+ },
+ },
refs: {
ref: [
{_type: 'cve', _id: 'CVE-2020-1234'},
diff --git a/src/web/pages/nvts/details.jsx b/src/web/pages/nvts/details.jsx
index 78b3c1b390..0355a4db93 100644
--- a/src/web/pages/nvts/details.jsx
+++ b/src/web/pages/nvts/details.jsx
@@ -19,7 +19,7 @@ import React from 'react';
import _ from 'gmp/locale';
-import {isDefined} from 'gmp/utils/identity';
+import {isDefined, isNumber} from 'gmp/utils/identity';
import {TAG_NA} from 'gmp/models/nvt';
@@ -44,9 +44,11 @@ import TableRow from 'web/components/table/row';
import References from './references';
import Solution from './solution';
import Pre from './preformatted';
+import CveLink from "web/components/link/cvelink.jsx";
const NvtDetails = ({entity, links = true}) => {
const {
+ epss,
tags = {},
severity,
qod,
@@ -67,6 +69,9 @@ const NvtDetails = ({entity, links = true}) => {
+
+ {_('CVSS')}
+
{_('CVSS Base')}
@@ -104,6 +109,80 @@ const NvtDetails = ({entity, links = true}) => {
)}
+ { isDefined(epss?.max_severity) &&
+ <>
+
+ {_('EPSS (CVE with highest severity)')}
+
+
+ {_('EPSS Score')}
+
+ {isNumber(epss?.max_severity?.score)
+ ? epss?.max_severity?.score.toFixed(5) : _("N/A")}
+
+
+
+ {_('EPSS Percentile')}
+
+ {isNumber(epss?.max_severity?.percentile)
+ ? epss?.max_severity?.percentile.toFixed(5) : _("N/A")}
+
+
+
+ {_('CVE')}
+
+
+ {epss?.max_severity?.cve?._id}
+
+
+
+
+ {_('CVE Severity')}
+
+
+ >
+ }
+ { isDefined(epss?.max_epss) &&
+ <>
+
+ {_('EPSS (highest EPSS score)')}
+
+
+ {_('EPSS Score')}
+
+ {isNumber(epss?.max_epss?.score)
+ ? epss?.max_epss?.score.toFixed(5) : _("N/A")}
+
+
+
+ {_('EPSS Percentile')}
+
+ {isNumber(epss?.max_epss?.percentile)
+ ? epss?.max_epss?.percentile.toFixed(5) : _("N/A")}
+
+
+
+ {_('CVE')}
+
+
+ {epss?.max_epss?.cve?._id}
+
+
+
+
+ {_('CVE Severity')}
+
+
+
+
+ >
+ }
diff --git a/src/web/pages/nvts/filterdialog.jsx b/src/web/pages/nvts/filterdialog.jsx
index 1fa7f54a1a..900b887c2d 100644
--- a/src/web/pages/nvts/filterdialog.jsx
+++ b/src/web/pages/nvts/filterdialog.jsx
@@ -56,6 +56,14 @@ const SORT_FIELDS = [
name: 'qod',
displayName: _l('QoD'),
},
+ {
+ name: 'epss_score',
+ displayName: _l('EPSS Score'),
+ },
+ {
+ name: 'epss_percentile',
+ displayName: _l('EPSS Percentile'),
+ },
];
export default createFilterDialog({
diff --git a/src/web/pages/nvts/row.jsx b/src/web/pages/nvts/row.jsx
index 892155c26e..7955065258 100644
--- a/src/web/pages/nvts/row.jsx
+++ b/src/web/pages/nvts/row.jsx
@@ -20,7 +20,7 @@ import React from 'react';
import Filter from 'gmp/models/filter.js';
-import {isDefined} from 'gmp/utils/identity';
+import {isDefined, isNumber} from 'gmp/utils/identity';
import SeverityBar from 'web/components/bar/severitybar';
@@ -42,6 +42,7 @@ import EntitiesActions from 'web/entities/actions';
import {RowDetailsToggle} from 'web/entities/row';
import PropTypes from 'web/utils/proptypes';
+import {_} from "gmp/locale/lang.js";
const Row = ({
actionsComponent: ActionsComponent = EntitiesActions,
@@ -101,6 +102,14 @@ const Row = ({
{entity.qod && }
+
+ {isNumber(entity?.epss?.max_severity?.score)
+ ? entity.epss?.max_severity?.score.toFixed(5) : _("N/A")}
+
+
+ {isNumber(entity?.epss?.max_severity?.percentile)
+ ? entity.epss?.max_severity?.percentile.toFixed(5) : _("N/A")}
+
);
diff --git a/src/web/pages/nvts/table.jsx b/src/web/pages/nvts/table.jsx
index 9b53df6ae1..c4e10bff3e 100644
--- a/src/web/pages/nvts/table.jsx
+++ b/src/web/pages/nvts/table.jsx
@@ -51,7 +51,8 @@ const Header = ({
-
+
{sort ? (
@@ -102,6 +107,7 @@ const Header = ({
+
+ {_("EPSS")}
+
{actionsColumn}
+
+
+
+
);
};