Skip to content

Commit

Permalink
[8.x] [Cloud Security] Vulnerabilities Preview & Refactor CSP Plugin …
Browse files Browse the repository at this point in the history
…PHASE 2 (elastic#193638) (elastic#195230)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Cloud Security] Vulnerabilities Preview & Refactor CSP Plugin PHASE
2 (elastic#193638)](elastic#193638)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Rickyanto
Ang","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-04T19:28:18Z","message":"[Cloud
Security] Vulnerabilities Preview & Refactor CSP Plugin PHASE 2
(elastic#193638)\n\nIn an attempt to make Reviewing easier and more accurate,
the\r\nimplementation of Vulnerabilities on Host.name flyout in Alerts
Page\r\nwill be split into 2 Phases\r\n\r\nPhase 1: Move Functions,
Utils or Helpers, Hooks, constants to Package\r\nPhase 2: Implementing
the feature\r\n\r\nThis is Phase 2\r\n<img width=\"1465\"
alt=\"Screenshot 2024-09-20 at 5 33
01 PM\"\r\nsrc=\"https://github.com/user-attachments/assets/cabe2f3a-d35a-4825-9fe5-61fe2d570328\">\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by:
Maxim Kholod
<[email protected]>","sha":"0b92c268f9e862812a4c2ab4ba50a3b90bc87a65","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Cloud
Security","backport:prev-minor","ci:build-cloud-image","ci:project-deploy-security","v8.16.0"],"number":193638,"url":"https://github.com/elastic/kibana/pull/193638","mergeCommit":{"message":"[Cloud
Security] Vulnerabilities Preview & Refactor CSP Plugin PHASE 2
(elastic#193638)\n\nIn an attempt to make Reviewing easier and more accurate,
the\r\nimplementation of Vulnerabilities on Host.name flyout in Alerts
Page\r\nwill be split into 2 Phases\r\n\r\nPhase 1: Move Functions,
Utils or Helpers, Hooks, constants to Package\r\nPhase 2: Implementing
the feature\r\n\r\nThis is Phase 2\r\n<img width=\"1465\"
alt=\"Screenshot 2024-09-20 at 5 33
01 PM\"\r\nsrc=\"https://github.com/user-attachments/assets/cabe2f3a-d35a-4825-9fe5-61fe2d570328\">\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by:
Maxim Kholod
<[email protected]>","sha":"0b92c268f9e862812a4c2ab4ba50a3b90bc87a65"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/193638","number":193638,"mergeCommit":{"message":"[Cloud
Security] Vulnerabilities Preview & Refactor CSP Plugin PHASE 2
(elastic#193638)\n\nIn an attempt to make Reviewing easier and more accurate,
the\r\nimplementation of Vulnerabilities on Host.name flyout in Alerts
Page\r\nwill be split into 2 Phases\r\n\r\nPhase 1: Move Functions,
Utils or Helpers, Hooks, constants to Package\r\nPhase 2: Implementing
the feature\r\n\r\nThis is Phase 2\r\n<img width=\"1465\"
alt=\"Screenshot 2024-09-20 at 5 33
01 PM\"\r\nsrc=\"https://github.com/user-attachments/assets/cabe2f3a-d35a-4825-9fe5-61fe2d570328\">\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by:
Maxim Kholod
<[email protected]>","sha":"0b92c268f9e862812a4c2ab4ba50a3b90bc87a65"}},{"branch":"8.x","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
animehart and kibanamachine authored Oct 8, 2024
1 parent 5de888f commit f9c640d
Show file tree
Hide file tree
Showing 31 changed files with 829 additions and 86 deletions.
10 changes: 10 additions & 0 deletions x-pack/packages/kbn-cloud-security-posture-common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { VulnSeverity } from './types/vulnerabilities';

export const KSPM_POLICY_TEMPLATE = 'kspm';
export const CSPM_POLICY_TEMPLATE = 'cspm';
export const CDR_LATEST_NATIVE_MISCONFIGURATIONS_INDEX_PATTERN =
Expand Down Expand Up @@ -33,3 +35,11 @@ export const CDR_LATEST_THIRD_PARTY_VULNERABILITIES_INDEX_PATTERN =
'security_solution-*.vulnerability_latest';
export const CDR_VULNERABILITIES_INDEX_PATTERN = `${CDR_LATEST_THIRD_PARTY_VULNERABILITIES_INDEX_PATTERN},${CDR_LATEST_NATIVE_VULNERABILITIES_INDEX_PATTERN}`;
export const LATEST_VULNERABILITIES_RETENTION_POLICY = '3d';

export const VULNERABILITIES_SEVERITY: Record<VulnSeverity, VulnSeverity> = {
LOW: 'LOW',
MEDIUM: 'MEDIUM',
HIGH: 'HIGH',
CRITICAL: 'CRITICAL',
UNKNOWN: 'UNKNOWN',
};
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe('test helper methods', () => {
filter: [
{
bool: {
should: [{ term: { 'host.name': { value: 'exampleHost' } } }],
should: [{ term: { 'host.name': 'exampleHost' } }],
minimum_should_match: 1,
},
},
Expand All @@ -171,7 +171,7 @@ describe('test helper methods', () => {
filter: [
{
bool: {
should: [{ term: { 'host.name': { value: '' } } }],
should: [{ term: { 'host.name': '' } }],
minimum_should_match: 1,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ export const buildEntityFlyoutPreviewQuery = (field: string, queryValue?: string
filter: [
{
bool: {
should: [{ term: { [field]: { value: `${queryValue || ''}` } } }],
should: [
{
term: {
[field]: `${queryValue || ''}`,
},
},
],
minimum_should_match: 1,
},
},
Expand Down
2 changes: 2 additions & 0 deletions x-pack/packages/kbn-cloud-security-posture/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export type { NavFilter } from './src/hooks/use_navigate_findings';
export { showErrorToast } from './src/utils/show_error_toast';
export { encodeQuery, decodeQuery } from './src/utils/query_utils';
export { CspEvaluationBadge } from './src/components/csp_evaluation_badge';
export { getSeverityStatusColor } from './src/utils/get_vulnerability_colors';
export { getSeverityText } from './src/utils/get_vulnerability_text';
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
CspClientPluginStartDeps,
LatestFindingsRequest,
LatestFindingsResponse,
UseMisconfigurationOptions,
UseCspOptions,
} from '../../type';

import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api';
Expand All @@ -23,7 +23,7 @@ import {
getMisconfigurationAggregationCount,
} from '../utils/hooks_utils';

export const useMisconfigurationFindings = (options: UseMisconfigurationOptions) => {
export const useMisconfigurationFindings = (options: UseCspOptions) => {
const {
data,
notifications: { toasts },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import type {
CspClientPluginStartDeps,
LatestFindingsRequest,
LatestFindingsResponse,
UseMisconfigurationOptions,
UseCspOptions,
} from '../../type';
import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api';
import {
buildMisconfigurationsFindingsQuery,
getMisconfigurationAggregationCount,
} from '../utils/hooks_utils';

export const useMisconfigurationPreview = (options: UseMisconfigurationOptions) => {
export const useMisconfigurationPreview = (options: UseCspOptions) => {
const {
data,
notifications: { toasts },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { lastValueFrom } from 'rxjs';
import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-types';
import {
SearchRequest,
SearchResponse,
AggregationsMultiBucketAggregateBase,
AggregationsStringRareTermsBucketKeys,
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import {
CDR_VULNERABILITIES_INDEX_PATTERN,
LATEST_VULNERABILITIES_RETENTION_POLICY,
} from '@kbn/cloud-security-posture-common';
import type { CspVulnerabilityFinding } from '@kbn/cloud-security-posture-common/schema/vulnerabilities/latest';
import type { CoreStart } from '@kbn/core/public';
import type { CspClientPluginStartDeps, UseCspOptions } from '../../type';
import { showErrorToast } from '../..';
import {
getFindingsCountAggQueryVulnerabilities,
getVulnerabilitiesAggregationCount,
} from '../utils/hooks_utils';

type LatestFindingsRequest = IKibanaSearchRequest<SearchRequest>;
type LatestFindingsResponse = IKibanaSearchResponse<
SearchResponse<CspVulnerabilityFinding, FindingsAggs>
>;

interface FindingsAggs {
count: AggregationsMultiBucketAggregateBase<AggregationsStringRareTermsBucketKeys>;
}

const getVulnerabilitiesQuery = ({ query }: UseCspOptions, isPreview = false) => ({
index: CDR_VULNERABILITIES_INDEX_PATTERN,
size: 0,
aggs: getFindingsCountAggQueryVulnerabilities(),
ignore_unavailable: true,
query: {
...query,
bool: {
...query?.bool,
filter: [
...(query?.bool?.filter ?? []),
{
range: {
'@timestamp': {
gte: `now-${LATEST_VULNERABILITIES_RETENTION_POLICY}`,
lte: 'now',
},
},
},
],
},
},
});

export const useVulnerabilitiesPreview = (options: UseCspOptions) => {
const {
data,
notifications: { toasts },
} = useKibana<CoreStart & CspClientPluginStartDeps>().services;

return useQuery(
['csp_vulnerabilities_preview', { params: options }],
async () => {
const {
rawResponse: { aggregations },
} = await lastValueFrom(
data.search.search<LatestFindingsRequest, LatestFindingsResponse>({
params: getVulnerabilitiesQuery(options),
})
);

return {
count: getVulnerabilitiesAggregationCount(aggregations?.count?.buckets),
};
},
{
keepPreviousData: true,
enabled: options.enabled,
onError: (err: Error) => showErrorToast(toasts, err),
}
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { euiThemeVars } from '@kbn/ui-theme';
import { getSeverityStatusColor } from './get_vulnerability_colors';
describe('getSeverityStatusColor', () => {
it('should return the correct color for LOW severity', () => {
expect(getSeverityStatusColor('LOW')).toBe(euiThemeVars.euiColorVis0);
});

it('should return the correct color for MEDIUM severity', () => {
expect(getSeverityStatusColor('MEDIUM')).toBe(euiThemeVars.euiColorVis5_behindText);
});

it('should return the correct color for HIGH severity', () => {
expect(getSeverityStatusColor('HIGH')).toBe(euiThemeVars.euiColorVis9_behindText);
});

it('should return the correct color for CRITICAL severity', () => {
expect(getSeverityStatusColor('CRITICAL')).toBe(euiThemeVars.euiColorDanger);
});

it('should return #aaa for an unknown severity', () => {
expect(getSeverityStatusColor('UNKNOWN')).toBe('#aaa');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { euiThemeVars } from '@kbn/ui-theme';
import type { VulnSeverity } from '@kbn/cloud-security-posture-common';
import { VULNERABILITIES_SEVERITY } from '@kbn/cloud-security-posture-common';

export const getSeverityStatusColor = (severity: VulnSeverity): string => {
switch (severity) {
case VULNERABILITIES_SEVERITY.LOW:
return euiThemeVars.euiColorVis0;
case VULNERABILITIES_SEVERITY.MEDIUM:
return euiThemeVars.euiColorVis5_behindText;
case VULNERABILITIES_SEVERITY.HIGH:
return euiThemeVars.euiColorVis9_behindText;
case VULNERABILITIES_SEVERITY.CRITICAL:
return euiThemeVars.euiColorDanger;
default:
return '#aaa';
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { getSeverityText } from './get_vulnerability_text';
describe('getSeverityStatusColor', () => {
it('should return the correct color for LOW severity', () => {
expect(getSeverityText('LOW')).toBe('Low');
});

it('should return the correct color for MEDIUM severity', () => {
expect(getSeverityText('MEDIUM')).toBe('Medium');
});

it('should return the correct color for HIGH severity', () => {
expect(getSeverityText('HIGH')).toBe('High');
});

it('should return the correct color for CRITICAL severity', () => {
expect(getSeverityText('CRITICAL')).toBe('Critical');
});

it('should return #aaa for an unknown severity', () => {
expect(getSeverityText('UNKNOWN')).toBe('None');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { VulnSeverity } from '@kbn/cloud-security-posture-common';
import { VULNERABILITIES_SEVERITY } from '@kbn/cloud-security-posture-common';

export const getSeverityText = (severity: VulnSeverity): string => {
switch (severity) {
case VULNERABILITIES_SEVERITY.LOW:
return 'Low';
case VULNERABILITIES_SEVERITY.MEDIUM:
return 'Medium';
case VULNERABILITIES_SEVERITY.HIGH:
return 'High';
case VULNERABILITIES_SEVERITY.CRITICAL:
return 'Critical';
default:
return 'None';
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import {
AggregationBuckets,
getVulnerabilitiesAggregationCount,
VULNERABILITIES_RESULT_EVALUATION,
} from './hooks_utils';

describe('getVulnerabilitiesAggregationCount', () => {
it('should return default counts when nothing is provided', () => {
const result = {
[VULNERABILITIES_RESULT_EVALUATION.LOW]: 0,
[VULNERABILITIES_RESULT_EVALUATION.MEDIUM]: 0,
[VULNERABILITIES_RESULT_EVALUATION.HIGH]: 0,
[VULNERABILITIES_RESULT_EVALUATION.CRITICAL]: 0,
[VULNERABILITIES_RESULT_EVALUATION.NONE]: 0,
};
expect(getVulnerabilitiesAggregationCount()).toEqual(result);
});

it('should return default counts when empty bucket is provided', () => {
const result = {
[VULNERABILITIES_RESULT_EVALUATION.LOW]: 0,
[VULNERABILITIES_RESULT_EVALUATION.MEDIUM]: 0,
[VULNERABILITIES_RESULT_EVALUATION.HIGH]: 0,
[VULNERABILITIES_RESULT_EVALUATION.CRITICAL]: 0,
[VULNERABILITIES_RESULT_EVALUATION.NONE]: 0,
};
expect(getVulnerabilitiesAggregationCount({})).toEqual(result);
});

it('should return counts when provided with non empty buckets', () => {
const buckets: AggregationBuckets = {
[VULNERABILITIES_RESULT_EVALUATION.LOW]: { doc_count: 1 },
[VULNERABILITIES_RESULT_EVALUATION.MEDIUM]: { doc_count: 2 },
[VULNERABILITIES_RESULT_EVALUATION.HIGH]: { doc_count: 3 },
[VULNERABILITIES_RESULT_EVALUATION.CRITICAL]: { doc_count: 4 },
[VULNERABILITIES_RESULT_EVALUATION.NONE]: { doc_count: 5 },
};

const vulnerabilitiesAggregrationCount = getVulnerabilitiesAggregationCount(
buckets as estypes.AggregationsBuckets<estypes.AggregationsStringRareTermsBucketKeys>
);
const result = {
[VULNERABILITIES_RESULT_EVALUATION.LOW]: 1,
[VULNERABILITIES_RESULT_EVALUATION.MEDIUM]: 2,
[VULNERABILITIES_RESULT_EVALUATION.HIGH]: 3,
[VULNERABILITIES_RESULT_EVALUATION.CRITICAL]: 4,
[VULNERABILITIES_RESULT_EVALUATION.NONE]: 5,
};
expect(vulnerabilitiesAggregrationCount).toEqual(result);
});
});
Loading

0 comments on commit f9c640d

Please sign in to comment.