[8.10] [RAM] Alert search strategy fields for security (#165040) (#165141)

# Backport

This will backport the following commits from `main` to `8.10`:
- [[RAM] Alert search strategy fields for security
(#165040)](https://github.com/elastic/kibana/pull/165040)

<!--- Backport version: 8.9.7 -->

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

<!--BACKPORT [{"author":{"name":"Xavier
Mouligneau","email":"xavier.mouligneau@elastic.co"},"sourceCommit":{"committedDate":"2023-08-29T17:18:28Z","message":"[RAM]
Alert search strategy fields for security (#165040)\n\n##
Summary\r\n\r\nFix =>
https://github.com/elastic/kibana/issues/164769\r\n\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"6b20ca94bc4cb352bbcdad4e849cf3c7fa166a79","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","impact:high","Team:ResponseOps","v8.10.0","v8.11.0"],"number":165040,"url":"https://github.com/elastic/kibana/pull/165040","mergeCommit":{"message":"[RAM]
Alert search strategy fields for security (#165040)\n\n##
Summary\r\n\r\nFix =>
https://github.com/elastic/kibana/issues/164769\r\n\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"6b20ca94bc4cb352bbcdad4e849cf3c7fa166a79"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/165040","number":165040,"mergeCommit":{"message":"[RAM]
Alert search strategy fields for security (#165040)\n\n##
Summary\r\n\r\nFix =>
https://github.com/elastic/kibana/issues/164769\r\n\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"6b20ca94bc4cb352bbcdad4e849cf3c7fa166a79"}}]}]
BACKPORT-->

Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>
This commit is contained in:
Kibana Machine 2023-08-29 14:37:24 -04:00 committed by GitHub
parent a13ba490b3
commit e451a3378e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 424 additions and 357 deletions

View file

@ -8,3 +8,4 @@
export * from './src/field_maps';
export * from './src/schemas';
export * from './src/search';

View file

@ -0,0 +1,13 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-alerts-as-data-utils'],
};

View file

@ -0,0 +1,9 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { buildAlertFieldsRequest, ALERT_EVENTS_FIELDS } from './security';

View file

@ -1,34 +1,36 @@
/*
* 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.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { buildFieldsRequest } from './build_fields_request';
import { TIMELINE_EVENTS_FIELDS } from './constants';
import { buildAlertFieldsRequest } from './build_fields_request';
import { ALERT_EVENTS_FIELDS } from './fields';
describe('buildFieldsRequest', () => {
it('should include ecs fields by default', () => {
const fields: string[] = [];
const fieldsRequest = buildFieldsRequest(fields);
expect(fieldsRequest).toHaveLength(TIMELINE_EVENTS_FIELDS.length);
const fieldsRequest = buildAlertFieldsRequest(fields);
expect(fieldsRequest).toHaveLength(ALERT_EVENTS_FIELDS.length);
});
it('should not show ecs fields', () => {
const fields: string[] = [];
const fieldsRequest = buildFieldsRequest(fields, true);
const fieldsRequest = buildAlertFieldsRequest(fields, true);
expect(fieldsRequest).toHaveLength(0);
});
it('should map the expected (non underscore prefixed) fields', () => {
const fields = ['_dontShow1', '_dontShow2', 'showsup'];
const fieldsRequest = buildFieldsRequest(fields, true);
const fieldsRequest = buildAlertFieldsRequest(fields, true);
expect(fieldsRequest).toEqual([{ field: 'showsup', include_unmapped: true }]);
});
it('should map provided fields with ecs fields', () => {
const fields = ['showsup'];
const fieldsRequest = buildFieldsRequest(fields);
expect(fieldsRequest).toHaveLength(TIMELINE_EVENTS_FIELDS.length + fields.length);
const fieldsRequest = buildAlertFieldsRequest(fields);
expect(fieldsRequest).toHaveLength(ALERT_EVENTS_FIELDS.length + fields.length);
});
});

View file

@ -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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { uniq } from 'lodash/fp';
import { ALERT_EVENTS_FIELDS } from './fields';
export const buildAlertFieldsRequest = (fields: string[], excludeEcsData?: boolean) =>
uniq([
...fields.filter((field) => !field.startsWith('_')),
...(excludeEcsData ? [] : ALERT_EVENTS_FIELDS),
]).map((field) => ({
field,
include_unmapped: true,
...(field === '@timestamp'
? {
format: 'strict_date_optional_time',
}
: {}),
}));

View file

@ -0,0 +1,289 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
ALERT_RULE_CONSUMER,
ALERT_RISK_SCORE,
ALERT_SEVERITY,
ALERT_RULE_PARAMETERS,
ALERT_WORKFLOW_TAGS,
} from '@kbn/rule-data-utils';
const ENRICHMENT_DESTINATION_PATH = 'threat.enrichments';
const MATCHED_ATOMIC = 'matched.atomic';
const MATCHED_FIELD = 'matched.field';
const MATCHED_TYPE = 'matched.type';
const INDICATOR_MATCHED_ATOMIC = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_ATOMIC}`;
const INDICATOR_MATCHED_FIELD = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_FIELD}`;
const INDICATOR_MATCHED_TYPE = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_TYPE}`;
const PROVIDER = 'indicator.provider';
const REFERENCE = 'indicator.reference';
const FEED_NAME = 'feed.name';
const INDICATOR_PROVIDER = `${ENRICHMENT_DESTINATION_PATH}.${PROVIDER}`;
const INDICATOR_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${REFERENCE}`;
const FEED_NAME_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${FEED_NAME}`;
const CTI_ROW_RENDERER_FIELDS = [
INDICATOR_MATCHED_ATOMIC,
INDICATOR_MATCHED_FIELD,
INDICATOR_MATCHED_TYPE,
INDICATOR_REFERENCE,
INDICATOR_PROVIDER,
FEED_NAME_REFERENCE,
];
// TODO: update all of these fields to use the constants from technical field names
export const ALERT_EVENTS_FIELDS = [
ALERT_RULE_CONSUMER,
'@timestamp',
'kibana.alert.ancestors.index',
'kibana.alert.workflow_status',
ALERT_WORKFLOW_TAGS,
'kibana.alert.group.id',
'kibana.alert.original_time',
'kibana.alert.reason',
'kibana.alert.rule.from',
'kibana.alert.rule.name',
'kibana.alert.rule.to',
'kibana.alert.rule.uuid',
'kibana.alert.rule.rule_id',
'kibana.alert.rule.type',
'kibana.alert.original_event.kind',
'kibana.alert.original_event.module',
'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',
'event.code',
'event.module',
'event.action',
'event.category',
'host.name',
'user.name',
'source.ip',
'destination.ip',
'message',
'system.auth.ssh.signature',
'system.auth.ssh.method',
'system.audit.package.arch',
'system.audit.package.entity_id',
'system.audit.package.name',
'system.audit.package.size',
'system.audit.package.summary',
'system.audit.package.version',
'event.created',
'event.dataset',
'event.duration',
'event.end',
'event.hash',
'event.id',
'event.kind',
'event.original',
'event.outcome',
'event.risk_score',
'event.risk_score_norm',
'event.severity',
'event.start',
'event.timezone',
'event.type',
'agent.type',
'agent.id',
'auditd.result',
'auditd.session',
'auditd.data.acct',
'auditd.data.terminal',
'auditd.data.op',
'auditd.summary.actor.primary',
'auditd.summary.actor.secondary',
'auditd.summary.object.primary',
'auditd.summary.object.secondary',
'auditd.summary.object.type',
'auditd.summary.how',
'auditd.summary.message_type',
'auditd.summary.sequence',
'file.Ext.original.path',
'file.name',
'file.target_path',
'file.extension',
'file.type',
'file.device',
'file.inode',
'file.uid',
'file.owner',
'file.gid',
'file.group',
'file.mode',
'file.size',
'file.mtime',
'file.ctime',
'file.path',
// NOTE: 7.10+ file.Ext.code_signature populated
// as array of objects, prior to that populated as
// single object
'file.Ext.code_signature',
'file.Ext.code_signature.subject_name',
'file.Ext.code_signature.trusted',
'file.hash.sha256',
'host.os.family',
'host.os.name',
'host.id',
'host.ip',
'registry.key',
'registry.path',
'rule.reference',
'source.bytes',
'source.packets',
'source.port',
'source.geo.continent_name',
'source.geo.country_name',
'source.geo.country_iso_code',
'source.geo.city_name',
'source.geo.region_iso_code',
'source.geo.region_name',
'destination.bytes',
'destination.packets',
'destination.port',
'destination.geo.continent_name',
'destination.geo.country_name',
'destination.geo.country_iso_code',
'destination.geo.city_name',
'destination.geo.region_iso_code',
'destination.geo.region_name',
'dns.question.name',
'dns.question.type',
'dns.resolved_ip',
'dns.response_code',
'endgame.exit_code',
'endgame.file_name',
'endgame.file_path',
'endgame.logon_type',
'endgame.parent_process_name',
'endgame.pid',
'endgame.process_name',
'endgame.subject_domain_name',
'endgame.subject_logon_id',
'endgame.subject_user_name',
'endgame.target_domain_name',
'endgame.target_logon_id',
'endgame.target_user_name',
'kibana.alert.rule.timeline_id',
'kibana.alert.rule.timeline_title',
'kibana.alert.rule.note',
'kibana.alert.rule.exceptions_list',
'kibana.alert.rule.building_block_type',
'suricata.eve.proto',
'suricata.eve.flow_id',
'suricata.eve.alert.signature',
'suricata.eve.alert.signature_id',
'network.bytes',
'network.community_id',
'network.direction',
'network.packets',
'network.protocol',
'network.transport',
'http.version',
'http.request.method',
'http.request.body.bytes',
'http.request.body.content',
'http.request.referrer',
'http.response.status_code',
'http.response.body.bytes',
'http.response.body.content',
'tls.client_certificate.fingerprint.sha1',
'tls.fingerprints.ja3.hash',
'tls.server_certificate.fingerprint.sha1',
'user.domain',
'winlog.event_id',
'process.end',
'process.entry_leader.entry_meta.type',
'process.entry_leader.entry_meta.source.ip',
'process.exit_code',
'process.hash.md5',
'process.hash.sha1',
'process.hash.sha256',
'process.interactive',
'process.parent.name',
'process.parent.pid',
'process.pid',
'process.name',
'process.ppid',
'process.args',
'process.entity_id',
'process.executable',
'process.start',
'process.title',
'process.working_directory',
'process.entry_leader.entity_id',
'process.entry_leader.name',
'process.entry_leader.pid',
'process.entry_leader.start',
'process.session_leader.entity_id',
'process.session_leader.name',
'process.session_leader.pid',
'process.group_leader.entity_id',
'process.group_leader.name',
'process.group_leader.pid',
'zeek.session_id',
'zeek.connection.local_resp',
'zeek.connection.local_orig',
'zeek.connection.missed_bytes',
'zeek.connection.state',
'zeek.connection.history',
'zeek.notice.suppress_for',
'zeek.notice.msg',
'zeek.notice.note',
'zeek.notice.sub',
'zeek.notice.dst',
'zeek.notice.dropped',
'zeek.notice.peer_descr',
'zeek.dns.AA',
'zeek.dns.qclass_name',
'zeek.dns.RD',
'zeek.dns.qtype_name',
'zeek.dns.qtype',
'zeek.dns.query',
'zeek.dns.trans_id',
'zeek.dns.qclass',
'zeek.dns.RA',
'zeek.dns.TC',
'zeek.http.resp_mime_types',
'zeek.http.trans_depth',
'zeek.http.status_msg',
'zeek.http.resp_fuids',
'zeek.http.tags',
'zeek.files.session_ids',
'zeek.files.timedout',
'zeek.files.local_orig',
'zeek.files.tx_host',
'zeek.files.source',
'zeek.files.is_orig',
'zeek.files.overflow_bytes',
'zeek.files.sha1',
'zeek.files.duration',
'zeek.files.depth',
'zeek.files.analyzers',
'zeek.files.mime_type',
'zeek.files.rx_host',
'zeek.files.total_bytes',
'zeek.files.fuid',
'zeek.files.seen_bytes',
'zeek.files.missing_bytes',
'zeek.files.md5',
'zeek.ssl.cipher',
'zeek.ssl.established',
'zeek.ssl.resumed',
'zeek.ssl.version',
...CTI_ROW_RENDERER_FIELDS,
];

View file

@ -0,0 +1,10 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { buildAlertFieldsRequest } from './build_fields_request';
export { ALERT_EVENTS_FIELDS } from './fields';

View file

@ -8,6 +8,7 @@ import { of } from 'rxjs';
import { merge } from 'lodash';
import { loggerMock } from '@kbn/logging-mocks';
import { AlertConsumers } from '@kbn/rule-data-utils';
import { ALERT_EVENTS_FIELDS } from '@kbn/alerts-as-data-utils';
import { ruleRegistrySearchStrategyProvider, EMPTY_RESPONSE } from './search_strategy';
import { dataPluginMock } from '@kbn/data-plugin/server/mocks';
import { SearchStrategyDependencies } from '@kbn/data-plugin/server';
@ -313,18 +314,31 @@ describe('ruleRegistrySearchStrategyProvider()', () => {
await strategy
.search(request, options, deps as unknown as SearchStrategyDependencies)
.toPromise();
expect(searchStrategySearch).toHaveBeenCalledWith(
{
params: {
const arg0 = searchStrategySearch.mock.calls[0][0];
expect(arg0.params.body.fields.length).toEqual(
// +2 because of fields.push({ field: 'kibana.alert.*', include_unmapped: false }); and
// fields.push({ field: 'signal.*', include_unmapped: false });
ALERT_EVENTS_FIELDS.length + 2
);
expect.arrayContaining([
expect.objectContaining({
x: 2,
y: 3,
}),
]);
expect(arg0).toEqual(
expect.objectContaining({
id: undefined,
params: expect.objectContaining({
allow_no_indices: true,
body: {
body: expect.objectContaining({
_source: false,
fields: [
{
field: '*',
fields: expect.arrayContaining([
expect.objectContaining({
field: '@timestamp',
include_unmapped: true,
},
],
}),
]),
from: 0,
query: {
ids: {
@ -333,13 +347,11 @@ describe('ruleRegistrySearchStrategyProvider()', () => {
},
size: 1000,
sort: [],
},
}),
ignore_unavailable: true,
index: ['security-siem'],
},
},
{},
{ request: {} }
}),
})
);
});
@ -349,7 +361,7 @@ describe('ruleRegistrySearchStrategyProvider()', () => {
query: {
ids: { values: ['test-id'] },
},
fields: [{ field: '@timestamp', include_unmapped: true }],
fields: [{ field: 'my-super-field', include_unmapped: true }],
};
const options = {};
const deps = {
@ -363,13 +375,26 @@ describe('ruleRegistrySearchStrategyProvider()', () => {
await strategy
.search(request, options, deps as unknown as SearchStrategyDependencies)
.toPromise();
expect(searchStrategySearch).toHaveBeenCalledWith(
{
params: {
const arg0 = searchStrategySearch.mock.calls[0][0];
expect(arg0.params.body.fields.length).toEqual(
// +2 because of fields.push({ field: 'kibana.alert.*', include_unmapped: false }); and
// fields.push({ field: 'signal.*', include_unmapped: false }); + my-super-field
ALERT_EVENTS_FIELDS.length + 3
);
expect(arg0).toEqual(
expect.objectContaining({
id: undefined,
params: expect.objectContaining({
allow_no_indices: true,
body: {
body: expect.objectContaining({
_source: false,
fields: [{ field: '@timestamp', include_unmapped: true }],
fields: expect.arrayContaining([
expect.objectContaining({
field: 'my-super-field',
include_unmapped: true,
}),
]),
from: 0,
query: {
ids: {
@ -378,13 +403,11 @@ describe('ruleRegistrySearchStrategyProvider()', () => {
},
size: 1000,
sort: [],
},
}),
ignore_unavailable: true,
index: ['security-siem'],
},
},
{},
{ request: {} }
}),
})
);
});
});

View file

@ -8,7 +8,6 @@ import { map, mergeMap, catchError } from 'rxjs/operators';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Logger } from '@kbn/core/server';
import { from, of } from 'rxjs';
import { isEmpty } from 'lodash';
import { isValidFeatureId, AlertConsumers } from '@kbn/rule-data-utils';
import { ENHANCED_ES_SEARCH_STRATEGY } from '@kbn/data-plugin/common';
import { ISearchStrategy, PluginStart } from '@kbn/data-plugin/server';
@ -19,6 +18,7 @@ import {
} from '@kbn/alerting-plugin/server';
import { SecurityPluginSetup } from '@kbn/security-plugin/server';
import { SpacesPluginStart } from '@kbn/spaces-plugin/server';
import { buildAlertFieldsRequest } from '@kbn/alerts-as-data-utils';
import {
RuleRegistrySearchRequest,
RuleRegistrySearchResponse,
@ -31,8 +31,6 @@ export const EMPTY_RESPONSE: RuleRegistrySearchResponse = {
rawResponse: {} as RuleRegistrySearchResponse['rawResponse'],
};
const EMPTY_FIELDS = [{ field: '*', include_unmapped: true }];
export const RULE_SEARCH_STRATEGY_NAME = 'privateRuleRegistryAlertsSearchStrategy';
export const ruleRegistrySearchStrategyProvider = (
@ -124,6 +122,17 @@ export const ruleRegistrySearchStrategyProvider = (
},
}),
};
let fields = request?.fields ?? [];
fields.push({ field: 'kibana.alert.*', include_unmapped: false });
if (siemRequest) {
fields.push({ field: 'signal.*', include_unmapped: false });
fields = fields.concat(buildAlertFieldsRequest([], false));
} else {
// only for o11y solutions
fields.push({ field: '*', include_unmapped: true });
}
const size = request.pagination ? request.pagination.pageSize : MAX_ALERT_SEARCH_SIZE;
params = {
allow_no_indices: true,
@ -131,8 +140,7 @@ export const ruleRegistrySearchStrategyProvider = (
ignore_unavailable: true,
body: {
_source: false,
// TODO the fields need to come from the request
fields: !isEmpty(request?.fields) ? request?.fields : EMPTY_FIELDS,
fields,
sort,
size,
from: request.pagination ? request.pagination.pageIndex * size : 0,

View file

@ -7,6 +7,7 @@
import { cloneDeep, getOr } from 'lodash/fp';
import type { IEsSearchResponse } from '@kbn/data-plugin/common';
import { buildAlertFieldsRequest as buildFieldsRequest } from '@kbn/alerts-as-data-utils';
import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants';
import {
EventHit,
@ -18,7 +19,6 @@ import {
import { TimelineFactory } from '../../types';
import { buildTimelineEventsAllQuery } from './query.events_all.dsl';
import { inspectStringifyObject } from '../../../../../utils/build_query';
import { buildFieldsRequest } from '../../helpers/build_fields_request';
import { formatTimelineData } from '../../helpers/format_timeline_data';
import { TIMELINE_EVENTS_FIELDS } from '../../helpers/constants';

View file

@ -1,18 +0,0 @@
/*
* 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 { uniq } from 'lodash/fp';
import { TIMELINE_EVENTS_FIELDS } from './constants';
export const buildFieldsRequest = (fields: string[], excludeEcsData?: boolean) =>
uniq([
...fields.filter((field) => !field.startsWith('_')),
...(excludeEcsData ? [] : TIMELINE_EVENTS_FIELDS),
]).map((field) => ({
field,
include_unmapped: true,
}));

View file

@ -5,292 +5,8 @@
* 2.0.
*/
import {
ALERT_RULE_CONSUMER,
ALERT_RISK_SCORE,
ALERT_SEVERITY,
ALERT_RULE_PARAMETERS,
ALERT_WORKFLOW_TAGS,
} from '@kbn/rule-data-utils';
import { ENRICHMENT_DESTINATION_PATH } from '../../../../../common/constants';
import { ALERT_EVENTS_FIELDS as TIMELINE_EVENTS_FIELDS } from '@kbn/alerts-as-data-utils';
export const MATCHED_ATOMIC = 'matched.atomic';
export const MATCHED_FIELD = 'matched.field';
export const MATCHED_TYPE = 'matched.type';
export const INDICATOR_MATCH_SUBFIELDS = [MATCHED_ATOMIC, MATCHED_FIELD, MATCHED_TYPE];
const ECS_METADATA_FIELDS = ['_id', '_index', '_type', '_score'];
export const INDICATOR_MATCHED_ATOMIC = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_ATOMIC}`;
export const INDICATOR_MATCHED_FIELD = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_FIELD}`;
export const INDICATOR_MATCHED_TYPE = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_TYPE}`;
export const EVENT_DATASET = 'event.dataset';
export const FIRST_SEEN = 'indicator.first_seen';
export const LAST_SEEN = 'indicator.last_seen';
export const PROVIDER = 'indicator.provider';
export const REFERENCE = 'indicator.reference';
export const FEED_NAME = 'feed.name';
export const INDICATOR_FIRSTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${FIRST_SEEN}`;
export const INDICATOR_LASTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${LAST_SEEN}`;
export const INDICATOR_PROVIDER = `${ENRICHMENT_DESTINATION_PATH}.${PROVIDER}`;
export const INDICATOR_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${REFERENCE}`;
export const FEED_NAME_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${FEED_NAME}`;
export const CTI_ROW_RENDERER_FIELDS = [
INDICATOR_MATCHED_ATOMIC,
INDICATOR_MATCHED_FIELD,
INDICATOR_MATCHED_TYPE,
INDICATOR_REFERENCE,
INDICATOR_PROVIDER,
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',
'kibana.alert.ancestors.index',
'kibana.alert.workflow_status',
ALERT_WORKFLOW_TAGS,
'kibana.alert.group.id',
'kibana.alert.original_time',
'kibana.alert.reason',
'kibana.alert.rule.from',
'kibana.alert.rule.name',
'kibana.alert.rule.to',
'kibana.alert.rule.uuid',
'kibana.alert.rule.rule_id',
'kibana.alert.rule.type',
'kibana.alert.original_event.kind',
'kibana.alert.original_event.module',
'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',
'event.code',
'event.module',
'event.action',
'event.category',
'host.name',
'user.name',
'source.ip',
'destination.ip',
'message',
'system.auth.ssh.signature',
'system.auth.ssh.method',
'system.audit.package.arch',
'system.audit.package.entity_id',
'system.audit.package.name',
'system.audit.package.size',
'system.audit.package.summary',
'system.audit.package.version',
'event.created',
'event.dataset',
'event.duration',
'event.end',
'event.hash',
'event.id',
'event.kind',
'event.original',
'event.outcome',
'event.risk_score',
'event.risk_score_norm',
'event.severity',
'event.start',
'event.timezone',
'event.type',
'agent.type',
'agent.id',
'auditd.result',
'auditd.session',
'auditd.data.acct',
'auditd.data.terminal',
'auditd.data.op',
'auditd.summary.actor.primary',
'auditd.summary.actor.secondary',
'auditd.summary.object.primary',
'auditd.summary.object.secondary',
'auditd.summary.object.type',
'auditd.summary.how',
'auditd.summary.message_type',
'auditd.summary.sequence',
'file.Ext.original.path',
'file.name',
'file.target_path',
'file.extension',
'file.type',
'file.device',
'file.inode',
'file.uid',
'file.owner',
'file.gid',
'file.group',
'file.mode',
'file.size',
'file.mtime',
'file.ctime',
'file.path',
// NOTE: 7.10+ file.Ext.code_signature populated
// as array of objects, prior to that populated as
// single object
'file.Ext.code_signature',
'file.Ext.code_signature.subject_name',
'file.Ext.code_signature.trusted',
'file.hash.sha256',
'host.os.family',
'host.os.name',
'host.id',
'host.ip',
'registry.key',
'registry.path',
'rule.reference',
'source.bytes',
'source.packets',
'source.port',
'source.geo.continent_name',
'source.geo.country_name',
'source.geo.country_iso_code',
'source.geo.city_name',
'source.geo.region_iso_code',
'source.geo.region_name',
'destination.bytes',
'destination.packets',
'destination.port',
'destination.geo.continent_name',
'destination.geo.country_name',
'destination.geo.country_iso_code',
'destination.geo.city_name',
'destination.geo.region_iso_code',
'destination.geo.region_name',
'dns.question.name',
'dns.question.type',
'dns.resolved_ip',
'dns.response_code',
'endgame.exit_code',
'endgame.file_name',
'endgame.file_path',
'endgame.logon_type',
'endgame.parent_process_name',
'endgame.pid',
'endgame.process_name',
'endgame.subject_domain_name',
'endgame.subject_logon_id',
'endgame.subject_user_name',
'endgame.target_domain_name',
'endgame.target_logon_id',
'endgame.target_user_name',
'kibana.alert.rule.timeline_id',
'kibana.alert.rule.timeline_title',
'kibana.alert.rule.note',
'kibana.alert.rule.exceptions_list',
'kibana.alert.rule.building_block_type',
'suricata.eve.proto',
'suricata.eve.flow_id',
'suricata.eve.alert.signature',
'suricata.eve.alert.signature_id',
'network.bytes',
'network.community_id',
'network.direction',
'network.packets',
'network.protocol',
'network.transport',
'http.version',
'http.request.method',
'http.request.body.bytes',
'http.request.body.content',
'http.request.referrer',
'http.response.status_code',
'http.response.body.bytes',
'http.response.body.content',
'tls.client_certificate.fingerprint.sha1',
'tls.fingerprints.ja3.hash',
'tls.server_certificate.fingerprint.sha1',
'user.domain',
'winlog.event_id',
'process.end',
'process.entry_leader.entry_meta.type',
'process.entry_leader.entry_meta.source.ip',
'process.exit_code',
'process.hash.md5',
'process.hash.sha1',
'process.hash.sha256',
'process.interactive',
'process.parent.name',
'process.parent.pid',
'process.pid',
'process.name',
'process.ppid',
'process.args',
'process.entity_id',
'process.executable',
'process.start',
'process.title',
'process.working_directory',
'process.entry_leader.entity_id',
'process.entry_leader.name',
'process.entry_leader.pid',
'process.entry_leader.start',
'process.session_leader.entity_id',
'process.session_leader.name',
'process.session_leader.pid',
'process.group_leader.entity_id',
'process.group_leader.name',
'process.group_leader.pid',
'zeek.session_id',
'zeek.connection.local_resp',
'zeek.connection.local_orig',
'zeek.connection.missed_bytes',
'zeek.connection.state',
'zeek.connection.history',
'zeek.notice.suppress_for',
'zeek.notice.msg',
'zeek.notice.note',
'zeek.notice.sub',
'zeek.notice.dst',
'zeek.notice.dropped',
'zeek.notice.peer_descr',
'zeek.dns.AA',
'zeek.dns.qclass_name',
'zeek.dns.RD',
'zeek.dns.qtype_name',
'zeek.dns.qtype',
'zeek.dns.query',
'zeek.dns.trans_id',
'zeek.dns.qclass',
'zeek.dns.RA',
'zeek.dns.TC',
'zeek.http.resp_mime_types',
'zeek.http.trans_depth',
'zeek.http.status_msg',
'zeek.http.resp_fuids',
'zeek.http.tags',
'zeek.files.session_ids',
'zeek.files.timedout',
'zeek.files.local_orig',
'zeek.files.tx_host',
'zeek.files.source',
'zeek.files.is_orig',
'zeek.files.overflow_bytes',
'zeek.files.sha1',
'zeek.files.duration',
'zeek.files.depth',
'zeek.files.analyzers',
'zeek.files.mime_type',
'zeek.files.rx_host',
'zeek.files.total_bytes',
'zeek.files.fuid',
'zeek.files.seen_bytes',
'zeek.files.missing_bytes',
'zeek.files.md5',
'zeek.ssl.cipher',
'zeek.ssl.established',
'zeek.ssl.resumed',
'zeek.ssl.version',
...CTI_ROW_RENDERER_FIELDS,
];
export const ECS_METADATA_FIELDS = ['_id', '_index', '_type', '_score'];
export { TIMELINE_EVENTS_FIELDS, ECS_METADATA_FIELDS };

View file

@ -39,8 +39,6 @@ export interface UseColumnsResp {
}>;
}
const EMPTY_FIELDS = [{ field: '*', include_unmapped: true }];
const fieldTypeToDataGridColumnTypeMapper = (fieldType: string | undefined) => {
if (fieldType === 'date') return 'datetime';
if (fieldType === 'number') return 'numeric';
@ -275,16 +273,8 @@ export const useColumns = ({
[columns, setColumnsAndSave, visibleColumns]
);
/*
* In some case such security, we need some special fields such as threat.enrichments which are
* not fetched when passing only EMPTY_FIELDS. Hence, we will fetch all the fields that user has added to the table.
*
* Additionally, system such as o11y needs fields which are not even added in the table such as rule_type_id and hence we
* additionly pass EMPTY_FIELDS so that it brings all fields apart from special fields
*
* */
const fieldsToFetch = useMemo(
() => [...columns.map((col) => ({ field: col.id, include_unmapped: true })), ...EMPTY_FIELDS],
() => [...columns.map((col) => ({ field: col.id, include_unmapped: true }))],
[columns]
);