[Cloud Security] updates to move from doc_root.vulnerability.package -> doc_root.package (ECS) (#164651)

## Summary

Issue: https://github.com/elastic/kibana/issues/157674

This updates all instances of vulnerability.package to the ECS standard
package fieldset.

The new field has been populated by cloudbeat since 8.8

### Checklist

Delete any items that are not applicable to this PR.

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Karl Godard 2023-08-24 09:08:59 -07:00 committed by GitHub
parent ec1b885082
commit fda98b0a88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 53 additions and 66 deletions

View file

@ -70,6 +70,11 @@ export interface CspVulnerabilityFinding {
commit_sha: string;
commit_time: string;
};
package: {
version: string;
name: string;
fixed_version?: string;
};
}
export interface Vulnerability {
@ -99,11 +104,6 @@ export interface Vulnerability {
scanner: {
vendor: string;
};
package: {
version: string;
name: string;
fixed_version?: string;
};
}
export interface VectorScoreBase {

View file

@ -27,6 +27,7 @@ export const mockVulnerabilityHit: CspVulnerabilityFinding = {
machine: { type: 'c6g.medium' },
region: 'eu-west-1',
},
package: { fixed_version: '0.4.0', version: 'v0.2.0', name: 'golang.org/x/net' },
vulnerability: {
published_date: '2022-08-10T00:00:00.000Z',
data_source: {
@ -34,7 +35,6 @@ export const mockVulnerabilityHit: CspVulnerabilityFinding = {
Name: 'The Go Vulnerability Database',
URL: 'https://github.com/golang/vulndb',
},
package: { fixed_version: '0.4.0', version: 'v0.2.0', name: 'golang.org/x/net' },
enumeration: 'CVE',
description:
'An attacker can cause excessive memory growth in a Go server accepting HTTP/2 requests. HTTP/2 server connections contain a cache of HTTP header keys sent by the client. While the total number of entries in this cache is capped, an attacker sending very large keys can cause the server to allocate approximately 64 MiB per open connection.',

View file

@ -127,12 +127,10 @@ describe('getRowValueByColumnId', () => {
it('should return package fields', () => {
const vulnerabilityRow = {
vulnerability: {
package: {
name: 'test',
version: '1.0.0',
fixed_version: '1.0.1',
},
package: {
name: 'test',
version: '1.0.0',
fixed_version: '1.0.1',
},
};
const columns1 = vulnerabilitiesColumns;

View file

@ -32,13 +32,13 @@ export const getRowValueByColumnId = (
return vulnerabilityRow.vulnerability?.severity;
}
if (columnId === columns.package) {
return vulnerabilityRow.vulnerability?.package?.name;
return vulnerabilityRow.package?.name;
}
if (columnId === columns.version) {
return vulnerabilityRow.vulnerability?.package?.version;
return vulnerabilityRow.package?.version;
}
if (columnId === columns.fixedVersion) {
return vulnerabilityRow.vulnerability?.package?.fixed_version;
return vulnerabilityRow.package?.fixed_version;
}
if (columnId === columns.region) {
return vulnerabilityRow.cloud?.region;

View file

@ -165,10 +165,8 @@ const VulnerabilitiesDataGrid = ({
(vulnerabilityRecord: VulnerabilitiesQueryData['page'][number]) =>
vulnerabilityRecord.vulnerability?.id === vulnerabilityRow.vulnerability?.id &&
vulnerabilityRecord.resource?.id === vulnerabilityRow.resource?.id &&
vulnerabilityRecord.vulnerability.package.name ===
vulnerabilityRow.vulnerability.package.name &&
vulnerabilityRecord.vulnerability.package.version ===
vulnerabilityRow.vulnerability.package.version
vulnerabilityRecord.package.name === vulnerabilityRow.package.name &&
vulnerabilityRecord.package.version === vulnerabilityRow.package.version
);
setUrlQuery({
vulnerabilityIndex,
@ -268,13 +266,13 @@ const VulnerabilitiesDataGrid = ({
}
if (columnId === vulnerabilitiesColumns.package) {
return <>{vulnerabilityRow.vulnerability?.package?.name}</>;
return <>{vulnerabilityRow?.package?.name}</>;
}
if (columnId === vulnerabilitiesColumns.version) {
return <>{vulnerabilityRow.vulnerability?.package?.version}</>;
return <>{vulnerabilityRow?.package?.version}</>;
}
if (columnId === vulnerabilitiesColumns.fixedVersion) {
return <>{vulnerabilityRow.vulnerability?.package?.fixed_version}</>;
return <>{vulnerabilityRow?.package?.fixed_version}</>;
}
return null;

View file

@ -124,10 +124,8 @@ const ResourceVulnerabilitiesDataGrid = ({
(vulnerabilityRecord: VulnerabilitiesQueryData['page'][number]) =>
vulnerabilityRecord.vulnerability?.id === vulnerabilityRow.vulnerability?.id &&
vulnerabilityRecord.resource?.id === vulnerabilityRow.resource?.id &&
vulnerabilityRecord.vulnerability.package.name ===
vulnerabilityRow.vulnerability.package.name &&
vulnerabilityRecord.vulnerability.package.version ===
vulnerabilityRow.vulnerability.package.version
vulnerabilityRecord.package.name === vulnerabilityRow.package.name &&
vulnerabilityRecord.package.version === vulnerabilityRow.package.version
);
setUrlQuery({
vulnerabilityIndex,
@ -232,13 +230,13 @@ const ResourceVulnerabilitiesDataGrid = ({
}
if (columnId === vulnerabilitiesColumns.package) {
return <>{vulnerabilityRow.vulnerability?.package?.name}</>;
return <>{vulnerabilityRow?.package?.name}</>;
}
if (columnId === vulnerabilitiesColumns.version) {
return <>{vulnerabilityRow.vulnerability?.package?.version}</>;
return <>{vulnerabilityRow?.package?.version}</>;
}
if (columnId === vulnerabilitiesColumns.fixedVersion) {
return <>{vulnerabilityRow.vulnerability?.package?.fixed_version}</>;
return <>{vulnerabilityRow?.package?.fixed_version}</>;
}
return null;

View file

@ -39,7 +39,7 @@ describe('<VulnerabilityFindingFlyout/>', () => {
getByText(mockVulnerabilityHit.vulnerability.description);
const descriptionList = getByTestId(FINDINGS_VULNERABILITY_FLYOUT_DESCRIPTION_LIST);
expect(descriptionList.textContent).toEqual(
`Resource ID:${mockVulnerabilityHit.resource?.id}Resource Name:${mockVulnerabilityHit.resource?.name}Package:${mockVulnerabilityHit.vulnerability.package.name}Version:${mockVulnerabilityHit.vulnerability.package.version}`
`Resource ID:${mockVulnerabilityHit.resource?.id}Resource Name:${mockVulnerabilityHit.resource?.name}Package:${mockVulnerabilityHit.package.name}Version:${mockVulnerabilityHit.package.version}`
);
getByText(mockVulnerabilityHit.vulnerability.severity);
});
@ -59,7 +59,7 @@ describe('<VulnerabilityFindingFlyout/>', () => {
it('show display Vulnerability details in a Overview Tab', () => {
const { getByText, getAllByText } = render(
<TestProvider>
<VulnerabilityOverviewTab vulnerability={mockVulnerabilityHit.vulnerability} />
<VulnerabilityOverviewTab vulnerabilityRecord={mockVulnerabilityHit} />
</TestProvider>
);
getByText(mockVulnerabilityHit.vulnerability.data_source.ID);
@ -72,7 +72,7 @@ describe('<VulnerabilityFindingFlyout/>', () => {
getAllByText(mockVulnerabilityHit.vulnerability?.cvss?.ghsa?.V3Vector?.toString() as string);
getAllByText(mockVulnerabilityHit.vulnerability?.cvss?.ghsa?.V3Score?.toString() as string);
getByText(
`${mockVulnerabilityHit.vulnerability.package.name} ${mockVulnerabilityHit.vulnerability.package.fixed_version}`
`${mockVulnerabilityHit.package.name} ${mockVulnerabilityHit.package.fixed_version}`
);
});
@ -80,9 +80,9 @@ describe('<VulnerabilityFindingFlyout/>', () => {
const { getByText } = render(
<TestProvider>
<VulnerabilityOverviewTab
vulnerability={{
...mockVulnerabilityHit.vulnerability,
package: { ...mockVulnerabilityHit.vulnerability.package, fixed_version: undefined },
vulnerabilityRecord={{
...mockVulnerabilityHit,
package: { ...mockVulnerabilityHit.package, fixed_version: undefined },
}}
/>
</TestProvider>

View file

@ -69,14 +69,14 @@ const getFlyoutDescriptionList = (
'xpack.csp.vulnerabilities.vulnerabilitiesFindingFlyout.flyoutDescriptionList.packageTitle',
{ defaultMessage: 'Package' }
),
description: vulnerabilityRecord.vulnerability.package.name,
description: vulnerabilityRecord.package.name,
},
{
title: i18n.translate(
'xpack.csp.vulnerabilities.vulnerabilitiesFindingFlyout.flyoutDescriptionList.versionTitle',
{ defaultMessage: 'Version' }
),
description: vulnerabilityRecord.vulnerability.package.version,
description: vulnerabilityRecord.package.version,
},
].filter(truthy);
@ -108,7 +108,7 @@ export const VulnerabilityFindingFlyout = ({
defaultMessage="Overview"
/>
),
content: <VulnerabilityOverviewTab vulnerability={vulnerability} />,
content: <VulnerabilityOverviewTab vulnerabilityRecord={vulnerabilityRecord} />,
},
{
id: tableTabId,
@ -131,7 +131,7 @@ export const VulnerabilityFindingFlyout = ({
content: <VulnerabilityJsonTab vulnerabilityRecord={vulnerabilityRecord} />,
},
],
[vulnerability, vulnerabilityRecord]
[vulnerabilityRecord]
);
const onSelectedTabChanged = (id: string) => setSelectedTabId(id);

View file

@ -19,7 +19,7 @@ import moment from 'moment';
import React from 'react';
import { euiThemeVars } from '@kbn/ui-theme';
import { i18n } from '@kbn/i18n';
import { VectorScoreBase, Vulnerability } from '../../../../common/schemas';
import { VectorScoreBase, CspVulnerabilityFinding } from '../../../../common/schemas';
import { CspFlyoutMarkdown } from '../../configurations/findings_flyout/findings_flyout';
import { NvdLogo } from '../../../assets/icons/nvd_logo_svg';
import { CVSScoreBadge } from '../../../components/vulnerability_badges';
@ -41,7 +41,7 @@ const vendorIcons: Record<string, string> = {
};
interface VulnerabilityTabProps {
vulnerability: Vulnerability;
vulnerabilityRecord: CspVulnerabilityFinding;
}
const CVSScore = ({ vectorBaseScore, vendor }: CVSScoreProps) => {
@ -135,7 +135,8 @@ const VectorScore = ({
);
};
const VulnerabilityOverviewTiles = ({ vulnerability }: VulnerabilityTabProps) => {
const VulnerabilityOverviewTiles = ({ vulnerabilityRecord }: VulnerabilityTabProps) => {
const { vulnerability } = vulnerabilityRecord;
const tileStyle = css`
padding: ${euiThemeVars.euiFontSizeM};
background: ${euiThemeVars.euiColorLightestShade};
@ -198,7 +199,8 @@ const VulnerabilityOverviewTiles = ({ vulnerability }: VulnerabilityTabProps) =>
);
};
export const VulnerabilityOverviewTab = ({ vulnerability }: VulnerabilityTabProps) => {
export const VulnerabilityOverviewTab = ({ vulnerabilityRecord }: VulnerabilityTabProps) => {
const { vulnerability } = vulnerabilityRecord;
const emptyFixesMessageState = i18n.translate(
'xpack.csp.vulnerabilities.vulnerabilityOverviewTab.emptyFixesMessage',
{
@ -206,8 +208,8 @@ export const VulnerabilityOverviewTab = ({ vulnerability }: VulnerabilityTabProp
}
);
const fixesDisplayText = vulnerability?.package?.fixed_version
? `${vulnerability?.package?.name} ${vulnerability?.package?.fixed_version}`
const fixesDisplayText = vulnerabilityRecord?.package?.fixed_version
? `${vulnerabilityRecord?.package?.name} ${vulnerabilityRecord?.package?.fixed_version}`
: emptyFixesMessageState;
const cvssScores: JSX.Element[] = vulnerability?.cvss
@ -236,7 +238,7 @@ export const VulnerabilityOverviewTab = ({ vulnerability }: VulnerabilityTabProp
return (
<EuiFlexGroup direction="column">
<EuiFlexItem>
<VulnerabilityOverviewTiles vulnerability={vulnerability} />
<VulnerabilityOverviewTiles vulnerabilityRecord={vulnerabilityRecord} />
</EuiFlexItem>
<EuiHorizontalRule css={horizontalStyle} />

View file

@ -16,9 +16,9 @@ export const vulnerabilitiesColumns = {
resourceName: 'resource.name',
resourceId: 'resource.id',
severity: 'vulnerability.severity',
package: 'vulnerability.package.name',
version: 'vulnerability.package.version',
fixedVersion: 'vulnerability.package.fixed_version',
package: 'package.name',
version: 'package.version',
fixedVersion: 'package.fixed_version',
};
const defaultColumnProps = () => ({

View file

@ -184,9 +184,7 @@ export const VulnerabilityTablePanelSection = () => {
),
render: (packageFixVersion: string) => (
<EuiLink
onClick={() =>
onCellClick({ 'vulnerability.package.fixed_version': packageFixVersion })
}
onClick={() => onCellClick({ 'package.fixed_version': packageFixVersion })}
className="eui-textTruncate"
color="text"
>
@ -276,7 +274,7 @@ export const VulnerabilityTablePanelSection = () => {
),
render: (packageName: string) => (
<EuiLink
onClick={() => onCellClick({ 'vulnerability.package.name': packageName })}
onClick={() => onCellClick({ 'package.name': packageName })}
className="eui-textTruncate"
color="text"
>
@ -295,7 +293,7 @@ export const VulnerabilityTablePanelSection = () => {
),
render: (packageVersion: string) => (
<EuiLink
onClick={() => onCellClick({ 'vulnerability.package.version': packageVersion })}
onClick={() => onCellClick({ 'package.version': packageVersion })}
className="eui-textTruncate"
color="text"
>
@ -314,9 +312,7 @@ export const VulnerabilityTablePanelSection = () => {
),
render: (packageFixVersion: string) => (
<EuiLink
onClick={() =>
onCellClick({ 'vulnerability.package.fixed_version': packageFixVersion })
}
onClick={() => onCellClick({ 'package.fixed_version': packageFixVersion })}
className="eui-textTruncate"
color="text"
>

View file

@ -38,12 +38,7 @@ export const latestVulnerabilitiesTransform: TransformPutTransformRequest = {
},
latest: {
sort: '@timestamp',
unique_key: [
'vulnerability.id',
'resource.id',
'vulnerability.package.name',
'vulnerability.package.version',
],
unique_key: ['vulnerability.id', 'resource.id', 'package.name', 'package.version'],
},
_meta: {
package: {

View file

@ -104,19 +104,19 @@ const getVulnerabilitiesQuery = (query: QueryDslQueryContainer): SearchRequest =
},
packageFixVersion: {
terms: {
field: 'vulnerability.package.fixed_version',
field: 'package.fixed_version',
size: 1,
},
},
packageName: {
terms: {
field: 'vulnerability.package.name',
field: 'package.name',
size: 1,
},
},
packageVersion: {
terms: {
field: 'vulnerability.package.version',
field: 'package.version',
size: 1,
},
},