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

change: cve.js for new data structure #4281

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions src/gmp/models/__tests__/cve.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ describe('CVE model tests', () => {
},
};
const cve = Cve.fromElement(elem);

expect(cve.products).toEqual(['foo:bar/dolor', 'ipsum:lorem']);
});

Expand Down Expand Up @@ -194,40 +193,6 @@ describe('CVE model tests', () => {
expect(cve.references).toEqual(res);
});

test('should parse cvss source', () => {
const elem = {
raw_data: {
entry: {
'published-datetime': '2018-10-10T11:41:23.022Z',
'last-modified-datetime': '2018-10-10T11:41:23.022Z',
cvss: {
base_metrics: {
source: 'prot://url',
},
},
},
},
};
const cve = Cve.fromElement(elem);

expect(cve.source).toEqual('prot://url');
});

test('should parse summary', () => {
const elem = {
raw_data: {
entry: {
'published-datetime': '2018-10-10T11:41:23.022Z',
'last-modified-datetime': '2018-10-10T11:41:23.022Z',
summary: 'lorem ipsum',
},
},
};
const cve = Cve.fromElement(elem);

expect(cve.description).toEqual('lorem ipsum');
});

test('should parse vulnerable products from raw data', () => {
const elem = {
raw_data: {
Expand All @@ -245,20 +210,6 @@ describe('CVE model tests', () => {
expect(cve.products).toEqual(['lorem', 'ipsum']);
});

test('should delete raw data', () => {
const elem = {
raw_data: {
entry: {
'published-datetime': {__text: '2018-10-10T11:41:23.022Z'},
'last-modified-datetime': {__text: '2018-10-10T11:41:23.022Z'},
},
},
};
const cve = Cve.fromElement(elem);

expect(cve.raw_data).toBeUndefined();
});

test('should return empty array for references if no raw data is given', () => {
const cve = Cve.fromElement({});

Expand Down
15 changes: 10 additions & 5 deletions src/gmp/models/cpe.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@
delete ret.update_time;
}

if (isDefined(ret.raw_data) && isDefined(ret.raw_data['cpe-item'])) {
const cpeItem = ret.raw_data['cpe-item'];
if (isDefined(cpeItem._deprecated_by)) {
ret.deprecatedBy = cpeItem._deprecated_by;
}
/*
* This code includes a backup check for deprecated field `raw_data`.
* Once `raw_data` is removed from the API, this backup check can be removed.
*/

if (ret.deprecated === 1 && isDefined(ret.deprecated_by)) {
ret.deprecatedBy = ret.deprecated_by._cpe_id;

Check warning on line 48 in src/gmp/models/cpe.js

View check run for this annotation

Codecov / codecov/patch

src/gmp/models/cpe.js#L48

Added line #L48 was not covered by tests
} else if (isDefined(ret.raw_data?.['cpe-item']?._deprecated_by)) {
ret.deprecatedBy = ret.raw_data['cpe-item']._deprecated_by;
}

return ret;
}
}
Expand Down
104 changes: 67 additions & 37 deletions src/gmp/models/cve.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {parseSeverity, parseDate, setProperties} from 'gmp/parser';
import {parseDate, parseSeverity, setProperties} from 'gmp/parser';
import {
parseCvssV2BaseFromVector,
parseCvssV3BaseFromVector,
Expand Down Expand Up @@ -114,52 +114,82 @@
}

ret.cvssBaseVector = ret.cvss_vector;
ret.products = isEmpty(ret.products) ? [] : ret.products.split(' ');

if (isDefined(ret.raw_data) && isDefined(ret.raw_data.entry)) {
const {entry} = ret.raw_data;

ret.publishedTime = parseDate(entry['published-datetime']);
ret.lastModifiedTime = parseDate(entry['last-modified-datetime']);
ret.products = isEmpty(ret.products) ? [] : ret.products.split(' ');

ret.references = map(entry.references, ref => ({
name: ref.reference.__text,
href: ref.reference._href,
/*
* The following code blocks for published-datetime, last-modified-datetime, products, and references
* include a backup check for deprecated field `raw_data`.
* Once `raw_data` is removed from the API, this check can be removed.
*/

ret.publishedTime = parseDate(
ret['creationTime'] ?? ret.raw_data?.entry?.['published-datetime'],
);
ret.lastModifiedTime = parseDate(
ret['modificationTime'] ??
ret.raw_data?.entry?.['last-modified-datetime'],
);

ret.references = [];
if (element.cve && isDefined(element.cve.references?.reference)) {
ret.references = map(element.cve.references.reference, ref => {
let tags = [];
if (isArray(ref.tags.tag)) {
tags = ref.tags.tag;
} else if (isDefined(ref.tags.tag)) {
tags = [ref.tags.tag];
}
return {
name: ref.url,
tags: tags,
href: ref.url,
};
});

Check warning on line 148 in src/gmp/models/cve.js

View check run for this annotation

Codecov / codecov/patch

src/gmp/models/cve.js#L136-L148

Added lines #L136 - L148 were not covered by tests
} else {
const {entry} = ret.raw_data ?? {};
const referencesList = entry?.references || [];
ret.references = map(referencesList, ref => ({
name: ref.reference?.__text,
href: ref.reference?._href,
source: ref.source,
reference_type: ref._reference_type,
}));
}

if (
isDefined(entry.cvss) &&
isDefined(entry.cvss.base_metrics) &&
isDefined(entry.cvss.base_metrics.source)
) {
ret.source = entry.cvss.base_metrics.source;
}

if (isDefined(entry.summary)) {
// really don't know why entry.summary and ret.description can differ
// but xslt did use the summary and and e.g. the description of
// CVE-2017-2988 was empty but summary not
ret.description = entry.summary;
}

const products = entry['vulnerable-software-list'];
if (isDefined(products)) {
if (isDefined(products.product)) {
ret.products = isArray(products.product)
? products.product
: [products.product];
} else {
ret.products = [];
if (
ret.products &&
ret.products.length === 0 &&
isDefined(element.cve?.configuration_nodes?.node)
) {
const nodes = isArray(element.cve.configuration_nodes.node)
? element.cve.configuration_nodes.node
: [element.cve.configuration_nodes.node];
nodes.forEach(node => {
if (
node.match_string?.vulnerable === 1 &&
isDefined(node.match_string?.matched_cpes?.cpe)
) {
const cpes = isArray(node.match_string.matched_cpes.cpe)
? node.match_string.matched_cpes.cpe
: [node.match_string.matched_cpes.cpe];
cpes.forEach(cpe => {
if (isDefined(cpe._id)) {
ret.products.push(cpe._id);
}
});

Check warning on line 180 in src/gmp/models/cve.js

View check run for this annotation

Codecov / codecov/patch

src/gmp/models/cve.js#L165-L180

Added lines #L165 - L180 were not covered by tests
}
}

delete ret.raw_data;
});

Check warning on line 182 in src/gmp/models/cve.js

View check run for this annotation

Codecov / codecov/patch

src/gmp/models/cve.js#L182

Added line #L182 was not covered by tests
} else {
ret.references = [];
const productsEntry =
ret.raw_data?.entry?.['vulnerable-software-list']?.product;
if (productsEntry) {
ret.products = isArray(productsEntry) ? productsEntry : [productsEntry];
}
}

ret.products = ret.products.filter(product => product !== '');

return ret;
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/web/pages/cves/detailspage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import _ from 'gmp/locale';
import {isDefined} from 'gmp/utils/identity';
import React from 'react';
import DateTime from 'web/components/date/datetime';
import CveIcon from 'web/components/icon/cveicon';
Expand Down Expand Up @@ -144,15 +145,23 @@
<div>{id}</div>
<div>{_('Published:')}</div>
<div>
<DateTime date={publishedTime} />
{isDefined(publishedTime) ? (
<DateTime date={publishedTime} />
) : (
_('N/A')

Check warning on line 151 in src/web/pages/cves/detailspage.jsx

View check run for this annotation

Codecov / codecov/patch

src/web/pages/cves/detailspage.jsx#L151

Added line #L151 was not covered by tests
)}
</div>
<div>{_('Modified:')}</div>
<div>
<DateTime date={updateTime} />
{isDefined(updateTime) ? <DateTime date={updateTime} /> : _('N/A')}
</div>
<div>{_('Last updated:')}</div>
<div>
<DateTime date={lastModifiedTime} />
{isDefined(lastModifiedTime) ? (
<DateTime date={lastModifiedTime} />
) : (
_('N/A')

Check warning on line 163 in src/web/pages/cves/detailspage.jsx

View check run for this annotation

Codecov / codecov/patch

src/web/pages/cves/detailspage.jsx#L163

Added line #L163 was not covered by tests
)}
</div>
</InfoLayout>
);
Expand Down
Loading