mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Security Solution][Investigations][Timeline] - Update getExceptions to use parameters (#145889)
## Summary Fixes: https://github.com/elastic/kibana/issues/136772 The issue was introduced by a couple of changes: First: https://github.com/elastic/kibana/pull/136163/files#diff-02d33a1ed6679f7775dc01941ca21b085d7c008ecffe5e029f5967407a5e5b13L23 in 8.4. The bug: A filter on the timeline UI relied on the `exceptions_list` field provided on `_source` to auto-generate a filter when investigating in timeline labelled `Not Exceptions` which would filter out the exceptions from the timeline. This PR resolves that issue by pulling the `exceptions_list` field from `kibana.alert.rule.parameters`. Second: https://github.com/elastic/kibana/pull/133254/files#diff-0f69b69fd9cefef6ed04a048d7df86b7e385e816bdf17309212437dc3f69726cL74 The filter actually stopped being passed to timeline entirely because of the above change. With the fixes in place: https://user-images.githubusercontent.com/17211684/203111748-7a0c2eb5-a46f-4f88-9d77-3628204625ac.mov
This commit is contained in:
parent
7198faf5ee
commit
b32c8b9df8
3 changed files with 82 additions and 53 deletions
|
@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux';
|
|||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ALERT_RULE_EXCEPTIONS_LIST } from '@kbn/rule-data-utils';
|
||||
import { ALERT_RULE_EXCEPTIONS_LIST, ALERT_RULE_PARAMETERS } from '@kbn/rule-data-utils';
|
||||
import type { ExceptionListId } from '@kbn/securitysolution-io-ts-list-types';
|
||||
import { useApi } from '@kbn/securitysolution-list-hooks';
|
||||
|
||||
|
@ -52,9 +52,27 @@ export const useInvestigateInTimeline = ({
|
|||
|
||||
const getExceptionFilter = useCallback(
|
||||
async (ecsData: Ecs): Promise<Filter | undefined> => {
|
||||
const exceptionsLists = (getField(ecsData, ALERT_RULE_EXCEPTIONS_LIST) ?? []).reduce(
|
||||
(acc: ExceptionListId[], next: string) => {
|
||||
const parsedList = JSON.parse(next);
|
||||
// This pulls exceptions list information from `_source`
|
||||
// This primarily matters for the old `signal` alerts a user may be viewing
|
||||
// as new exception lists are pulled from kibana.alert.rule.parameters[0].exception_lists;
|
||||
// Source was removed in favour of the fields api which passes the exceptions_list via `kibana.alert.rule.parameters`
|
||||
let exceptionsList = getField(ecsData, ALERT_RULE_EXCEPTIONS_LIST) ?? [];
|
||||
|
||||
if (exceptionsList.length === 0) {
|
||||
try {
|
||||
const ruleParameters = getField(ecsData, ALERT_RULE_PARAMETERS) ?? {};
|
||||
if (ruleParameters.length > 0) {
|
||||
const parametersObject = JSON.parse(ruleParameters[0]);
|
||||
exceptionsList = parametersObject?.exceptions_list ?? [];
|
||||
}
|
||||
} catch (error) {
|
||||
// do nothing, just fail silently as parametersObject is initialized
|
||||
}
|
||||
}
|
||||
const detectionExceptionsLists = exceptionsList.reduce(
|
||||
(acc: ExceptionListId[], next: string | object) => {
|
||||
// parsed rule.parameters returns an object else use the default string representation
|
||||
const parsedList = typeof next === 'string' ? JSON.parse(next) : next;
|
||||
if (parsedList.type === 'detection') {
|
||||
const formattedList = {
|
||||
exception_list_id: parsedList.list_id,
|
||||
|
@ -67,14 +85,15 @@ export const useInvestigateInTimeline = ({
|
|||
[]
|
||||
);
|
||||
|
||||
if (exceptionsLists.length > 0) {
|
||||
let exceptionFilter;
|
||||
if (detectionExceptionsLists.length > 0) {
|
||||
await getExceptionFilterFromIds({
|
||||
exceptionListIds: exceptionsLists,
|
||||
exceptionListIds: detectionExceptionsLists,
|
||||
excludeExceptions: true,
|
||||
chunkSize: 20,
|
||||
alias: 'Exceptions',
|
||||
onSuccess: (filter) => {
|
||||
return filter;
|
||||
exceptionFilter = filter;
|
||||
},
|
||||
onError: (err: string[]) => {
|
||||
addError(err, {
|
||||
|
@ -86,7 +105,7 @@ export const useInvestigateInTimeline = ({
|
|||
},
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
return exceptionFilter;
|
||||
},
|
||||
[addError, getExceptionFilterFromIds]
|
||||
);
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ALERT_RULE_CONSUMER, ALERT_RISK_SCORE, ALERT_SEVERITY } from '@kbn/rule-data-utils';
|
||||
import {
|
||||
ALERT_RULE_CONSUMER,
|
||||
ALERT_RISK_SCORE,
|
||||
ALERT_SEVERITY,
|
||||
ALERT_RULE_PARAMETERS,
|
||||
} from '@kbn/rule-data-utils';
|
||||
import { ENRICHMENT_DESTINATION_PATH } from '../../../../../common/constants';
|
||||
|
||||
export const MATCHED_ATOMIC = 'matched.atomic';
|
||||
|
@ -40,6 +45,7 @@ export const CTI_ROW_RENDERER_FIELDS = [
|
|||
FEED_NAME_REFERENCE,
|
||||
];
|
||||
|
||||
// TODO: update all of these fields to use the constants from technical field names
|
||||
export const TIMELINE_EVENTS_FIELDS = [
|
||||
ALERT_RULE_CONSUMER,
|
||||
'@timestamp',
|
||||
|
@ -58,6 +64,7 @@ export const TIMELINE_EVENTS_FIELDS = [
|
|||
'kibana.alert.rule.version',
|
||||
ALERT_SEVERITY,
|
||||
ALERT_RISK_SCORE,
|
||||
ALERT_RULE_PARAMETERS,
|
||||
'kibana.alert.threshold_result',
|
||||
'kibana.alert.building_block_type',
|
||||
'kibana.alert.suppression.docs_count',
|
||||
|
|
|
@ -414,6 +414,50 @@ describe('formatTimelineData', () => {
|
|||
field: 'kibana.alert.rule.uuid',
|
||||
value: ['15d82f10-0926-11ed-bece-6b0c033d0075'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.sourceId',
|
||||
value: ['default'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.nodeType',
|
||||
value: ['host'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.comparator',
|
||||
value: ['>'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.timeSize',
|
||||
value: ['1'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.metric',
|
||||
value: ['cpu'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.threshold',
|
||||
value: ['10'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.aggregation',
|
||||
value: ['avg'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.id',
|
||||
value: ['alert-custom-metric'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.field',
|
||||
value: [''],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.type',
|
||||
value: ['custom'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.timeUnit',
|
||||
value: ['d'],
|
||||
},
|
||||
{
|
||||
field: 'event.action',
|
||||
value: ['active'],
|
||||
|
@ -466,50 +510,6 @@ describe('formatTimelineData', () => {
|
|||
field: 'kibana.version',
|
||||
value: ['8.4.0'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.sourceId',
|
||||
value: ['default'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.nodeType',
|
||||
value: ['host'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.comparator',
|
||||
value: ['>'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.timeSize',
|
||||
value: ['1'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.metric',
|
||||
value: ['cpu'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.threshold',
|
||||
value: ['10'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.aggregation',
|
||||
value: ['avg'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.id',
|
||||
value: ['alert-custom-metric'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.field',
|
||||
value: [''],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.customMetric.type',
|
||||
value: ['custom'],
|
||||
},
|
||||
{
|
||||
field: 'kibana.alert.rule.parameters.criteria.timeUnit',
|
||||
value: ['d'],
|
||||
},
|
||||
],
|
||||
ecs: {
|
||||
'@timestamp': ['2022-07-21T22:38:57.888Z'],
|
||||
|
@ -528,6 +528,9 @@ describe('formatTimelineData', () => {
|
|||
consumer: ['infrastructure'],
|
||||
name: ['test 1212'],
|
||||
uuid: ['15d82f10-0926-11ed-bece-6b0c033d0075'],
|
||||
parameters: [
|
||||
'{"sourceId":"default","nodeType":"host","criteria":[{"comparator":">","timeSize":1,"metric":"cpu","threshold":[10],"customMetric":{"aggregation":"avg","id":"alert-custom-metric","field":"","type":"custom"},"timeUnit":"d"}]}',
|
||||
],
|
||||
},
|
||||
workflow_status: ['open'],
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue