mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution] Fixing exceptions flyout is not auto filled with all highlighted fields listed on Alert details page (#161673)
## Summary
- Addresses https://github.com/elastic/kibana/issues/161460
- Exclude `agent.id` in case the Alert's `agent.type` is not `endpoint`
- Handle Alert `event.category` array field ex. `[process]`
- For the `Threshold Rule` there are two additional fields the Alert
Summary populates the `Event Count` and the `Event Cardinality` which
can be ignored as they are not relevant to the Rule exception

### Checklist
- [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
This commit is contained in:
parent
ccb36d929a
commit
130e9deea5
3 changed files with 73 additions and 7 deletions
|
@ -51,6 +51,7 @@ import {
|
|||
ALERT_ORIGINAL_EVENT_KIND,
|
||||
ALERT_ORIGINAL_EVENT_MODULE,
|
||||
} from '../../../../common/field_maps/field_names';
|
||||
import { AGENT_ID } from './highlighted_fields_config';
|
||||
jest.mock('uuid', () => ({
|
||||
v4: jest.fn().mockReturnValue('123'),
|
||||
}));
|
||||
|
@ -1528,6 +1529,7 @@ describe('Exception helpers', () => {
|
|||
'event.category': 'malware',
|
||||
'event.type': 'creation',
|
||||
'event.dataset': 'endpoint',
|
||||
'kibana.alert.rule.uuid': '123',
|
||||
'kibana.alert.rule.exceptions_list': [
|
||||
{
|
||||
id: 'endpoint_list',
|
||||
|
@ -1714,17 +1716,18 @@ describe('Exception helpers', () => {
|
|||
describe('filterHighlightedFields', () => {
|
||||
const prefixesToExclude = ['agent', 'cloud'];
|
||||
it('should not filter any field if no prefixes passed ', () => {
|
||||
const filteredFields = filterHighlightedFields(expectedHighlightedFields, []);
|
||||
const filteredFields = filterHighlightedFields(expectedHighlightedFields, [], alertData);
|
||||
expect(filteredFields).toEqual(expectedHighlightedFields);
|
||||
});
|
||||
it('should not filter any field if no fields passed ', () => {
|
||||
const filteredFields = filterHighlightedFields([], prefixesToExclude);
|
||||
const filteredFields = filterHighlightedFields([], prefixesToExclude, alertData);
|
||||
expect(filteredFields).toEqual([]);
|
||||
});
|
||||
it('should filter out the passed prefixes successfully', () => {
|
||||
const filteredFields = filterHighlightedFields(
|
||||
expectedHighlightedFields,
|
||||
prefixesToExclude
|
||||
prefixesToExclude,
|
||||
alertData
|
||||
);
|
||||
expect(filteredFields).not.toEqual(
|
||||
expect.arrayContaining([
|
||||
|
@ -1845,6 +1848,24 @@ describe('Exception helpers', () => {
|
|||
},
|
||||
]);
|
||||
});
|
||||
it('should return the process highlighted fields correctly when eventCategory is an array', () => {
|
||||
const alertDataEventCategoryProcessArray = { ...alertData, 'event.category': ['process'] };
|
||||
const res = getAlertHighlightedFields(alertDataEventCategoryProcessArray);
|
||||
expect(res).not.toEqual(
|
||||
expect.arrayContaining([
|
||||
{ id: 'file.name' },
|
||||
{ id: 'file.hash.sha256' },
|
||||
{ id: 'file.directory' },
|
||||
])
|
||||
);
|
||||
expect(res).toEqual(
|
||||
expect.arrayContaining([
|
||||
{ id: 'process.name' },
|
||||
{ id: 'process.parent.name' },
|
||||
{ id: 'process.args' },
|
||||
])
|
||||
);
|
||||
});
|
||||
it('should return all highlighted fields even when the "kibana.alert.rule.type" is not in the alertData', () => {
|
||||
const alertDataWithoutEventCategory = { ...alertData, 'kibana.alert.rule.type': null };
|
||||
const res = getAlertHighlightedFields(alertDataWithoutEventCategory);
|
||||
|
@ -1856,6 +1877,22 @@ describe('Exception helpers', () => {
|
|||
const res = getAlertHighlightedFields(alertData);
|
||||
expect(res).toEqual(allHighlightFields);
|
||||
});
|
||||
it('should exclude the "agent.id" from highlighted fields when agent.type is not "endpoint"', () => {
|
||||
jest.mock('./highlighted_fields_config', () => ({ highlightedFieldsPrefixToExclude: [] }));
|
||||
|
||||
const alertDataWithoutAgentType = { ...alertData, agent: { ...alertData.agent, type: '' } };
|
||||
const res = getAlertHighlightedFields(alertDataWithoutAgentType);
|
||||
|
||||
expect(res).toEqual(allHighlightFields.filter((field) => field.id !== AGENT_ID));
|
||||
});
|
||||
it('should exclude the "agent.id" from highlighted fields when "kibana.alert.rule.uuid" is not part of the alertData', () => {
|
||||
jest.mock('./highlighted_fields_config', () => ({ highlightedFieldsPrefixToExclude: [] }));
|
||||
|
||||
const alertDataWithoutRuleUUID = { ...alertData, 'kibana.alert.rule.uuid': '' };
|
||||
const res = getAlertHighlightedFields(alertDataWithoutRuleUUID);
|
||||
|
||||
expect(res).toEqual(allHighlightFields.filter((field) => field.id !== AGENT_ID));
|
||||
});
|
||||
});
|
||||
describe('getPrepopulatedRuleExceptionWithHighlightFields', () => {
|
||||
it('should not create any exception and return null if there are no highlighted fields', () => {
|
||||
|
|
|
@ -59,6 +59,10 @@ import {
|
|||
getKibanaAlertIdField,
|
||||
highlightedFieldsPrefixToExclude,
|
||||
KIBANA_ALERT_RULE_TYPE,
|
||||
AGENT_ID,
|
||||
AGENT_TYPE,
|
||||
KIBANA_ALERT_RULE_UUID,
|
||||
ENDPOINT_ALERT,
|
||||
} from './highlighted_fields_config';
|
||||
|
||||
export const filterIndexPatterns = (
|
||||
|
@ -958,13 +962,19 @@ export const getPrepopulatedRuleExceptionWithHighlightFields = ({
|
|||
|
||||
/**
|
||||
Filters out the irrelevant highlighted fields for Rule exceptions using
|
||||
the "highlightedFieldsPrefixToExclude" array.
|
||||
1. The "highlightedFieldsPrefixToExclude" array
|
||||
2. Agent.id field in case the alert was not generated from Endpoint
|
||||
3. Threshold Rule
|
||||
*/
|
||||
export const filterHighlightedFields = (
|
||||
fields: EventSummaryField[],
|
||||
prefixesToExclude: string[]
|
||||
prefixesToExclude: string[],
|
||||
alertData: AlertData
|
||||
): EventSummaryField[] => {
|
||||
return fields.filter(({ id }) => {
|
||||
// Exclude agent.id field only if the agent type was not Endpoint
|
||||
if (id === AGENT_ID) return isAlertFromEndpointEvent(alertData);
|
||||
|
||||
return !prefixesToExclude.some((field: string) => id.startsWith(field));
|
||||
});
|
||||
};
|
||||
|
@ -974,6 +984,7 @@ export const filterHighlightedFields = (
|
|||
* * event.category
|
||||
* * event.code
|
||||
* * kibana.alert.rule.type
|
||||
* * Alert field ids filters
|
||||
* @param alertData The Alert data object
|
||||
*/
|
||||
export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryField[] => {
|
||||
|
@ -982,7 +993,7 @@ export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryFie
|
|||
const eventRuleType = get(alertData, KIBANA_ALERT_RULE_TYPE);
|
||||
|
||||
const eventCategories = {
|
||||
primaryEventCategory: eventCategory,
|
||||
primaryEventCategory: Array.isArray(eventCategory) ? eventCategory[0] : eventCategory,
|
||||
allEventCategories: [eventCategory],
|
||||
};
|
||||
|
||||
|
@ -991,5 +1002,19 @@ export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryFie
|
|||
eventCode,
|
||||
eventRuleType,
|
||||
});
|
||||
return filterHighlightedFields(fieldsToDisplay, highlightedFieldsPrefixToExclude);
|
||||
return filterHighlightedFields(fieldsToDisplay, highlightedFieldsPrefixToExclude, alertData);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks to see if the given set of Timeline event detail items includes data that indicates its
|
||||
* an endpoint Alert
|
||||
*/
|
||||
export const isAlertFromEndpointEvent = (alertData: AlertData) => {
|
||||
// Check to see if a timeline event item is an Alert
|
||||
const isTimelineEventItemAnAlert = get(alertData, KIBANA_ALERT_RULE_UUID);
|
||||
if (!isTimelineEventItemAnAlert) return false;
|
||||
|
||||
const agentTypes = get(alertData, AGENT_TYPE);
|
||||
const agentType = Array.isArray(agentTypes) ? agentTypes[0] : agentTypes;
|
||||
return agentType === ENDPOINT_ALERT;
|
||||
};
|
||||
|
|
|
@ -18,3 +18,7 @@ export const getKibanaAlertIdField = (id: string) => `kibana.alert.${id}`;
|
|||
export const EVENT_CATEGORY = 'event.category';
|
||||
export const EVENT_CODE = 'event.code';
|
||||
export const KIBANA_ALERT_RULE_TYPE = 'kibana.alert.rule.type';
|
||||
export const AGENT_ID = 'agent.id';
|
||||
export const AGENT_TYPE = 'agent.type';
|
||||
export const KIBANA_ALERT_RULE_UUID = 'kibana.alert.rule.uuid';
|
||||
export const ENDPOINT_ALERT = 'endpoint';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue