diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/queries/query_eql.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/queries/query_eql.json index 598f2182002c1d..a63444012addd6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/queries/query_eql.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/queries/query_eql.json @@ -25,6 +25,7 @@ "from": "now-300m", "severity": "high", "type": "eql", + "language": "eql", "threat": [ { "framework": "MITRE ATT&CK", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index b37bc7d0fab69c..501cd1fa6ecfb2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -22,6 +22,7 @@ import { RuleTypeParams } from '../../types'; import { IRuleStatusAttributes } from '../../rules/types'; import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings'; import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; +import { RulesSchema } from '../../../../../common/detection_engine/schemas/response'; export const sampleRuleAlertParams = ( maxSignals?: number | undefined, @@ -92,6 +93,46 @@ export const sampleRuleSO = (): SavedObject => { }; }; +export const expectedRule = (): RulesSchema => { + return { + actions: [], + author: ['Elastic'], + building_block_type: 'default', + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + rule_id: 'rule-1', + false_positives: [], + max_signals: 10000, + risk_score: 50, + risk_score_mapping: [], + output_index: '.siem-signals', + description: 'Detecting root and admin users', + from: 'now-6m', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + interval: '5m', + language: 'kuery', + license: 'Elastic License', + name: 'rule-name', + query: 'user.name: root or user.name: admin', + references: ['http://google.com'], + severity: 'high', + severity_mapping: [], + tags: ['some fake tag 1', 'some fake tag 2'], + threat: [], + type: 'query', + to: 'now', + note: '', + enabled: true, + created_by: 'sample user', + updated_by: 'sample user', + version: 1, + updated_at: '2020-03-27T22:55:59.577Z', + created_at: '2020-03-27T22:55:59.577Z', + throttle: 'no_actions', + exceptions_list: getListArrayMock(), + }; +}; + export const sampleDocNoSortIdNoVersion = (someUuid: string = sampleIdGuid): SignalSourceHit => ({ _index: 'myFakeSignalIndex', _type: 'doc', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts index f45a408cd32b8e..2f7dd22c0c78e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts @@ -546,7 +546,7 @@ describe('buildSignalFromEvent', () => { const ancestor = sampleDocWithAncestors().hits.hits[0]; delete ancestor._source.source; const ruleSO = sampleRuleSO(); - const signal = buildSignalFromEvent(ancestor, ruleSO); + const signal = buildSignalFromEvent(ancestor, ruleSO, true); // Timestamp will potentially always be different so remove it for the test // @ts-expect-error delete signal['@timestamp']; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts index 01a6b0e7aefadb..f8632a85c77e9e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts @@ -13,7 +13,7 @@ import { BaseSignalHit, SignalSource, } from './types'; -import { buildRule, buildRuleWithoutOverrides } from './build_rule'; +import { buildRule, buildRuleWithoutOverrides, buildRuleWithOverrides } from './build_rule'; import { additionalSignalFields, buildSignal } from './build_signal'; import { buildEventTypeSignal } from './build_event_type_signal'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; @@ -97,7 +97,7 @@ export const buildSignalGroupFromSequence = ( ): BaseSignalHit[] => { const wrappedBuildingBlocks = wrapBuildingBlocks( sequence.events.map((event) => { - const signal = buildSignalFromEvent(event, ruleSO); + const signal = buildSignalFromEvent(event, ruleSO, false); signal.signal.rule.building_block_type = 'default'; return signal; }), @@ -147,9 +147,12 @@ export const buildSignalFromSequence = ( export const buildSignalFromEvent = ( event: BaseSignalHit, - ruleSO: SavedObject + ruleSO: SavedObject, + applyOverrides: boolean ): SignalHit => { - const rule = buildRuleWithoutOverrides(ruleSO); + const rule = applyOverrides + ? buildRuleWithOverrides(ruleSO, event._source) + : buildRuleWithoutOverrides(ruleSO); const signal = { ...buildSignal([event], rule), ...additionalSignalFields(event), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts index 62e5854037d9e1..6bc9489f658707 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts @@ -4,12 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { buildRule, removeInternalTagsFromRule, buildRuleWithoutOverrides } from './build_rule'; +import { + buildRule, + removeInternalTagsFromRule, + buildRuleWithOverrides, + buildRuleWithoutOverrides, +} from './build_rule'; import { sampleDocNoSortId, sampleRuleAlertParams, sampleRuleGuid, sampleRuleSO, + expectedRule, + sampleDocSeverity, } from './__mocks__/es_results'; import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema'; import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; @@ -312,43 +319,7 @@ describe('buildRuleWithoutOverrides', () => { test('builds a rule using rule SO', () => { const ruleSO = sampleRuleSO(); const rule = buildRuleWithoutOverrides(ruleSO); - expect(rule).toEqual({ - actions: [], - author: ['Elastic'], - building_block_type: 'default', - id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - rule_id: 'rule-1', - false_positives: [], - max_signals: 10000, - risk_score: 50, - risk_score_mapping: [], - output_index: '.siem-signals', - description: 'Detecting root and admin users', - from: 'now-6m', - immutable: false, - index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - interval: '5m', - language: 'kuery', - license: 'Elastic License', - name: 'rule-name', - query: 'user.name: root or user.name: admin', - references: ['http://google.com'], - severity: 'high', - severity_mapping: [], - tags: ['some fake tag 1', 'some fake tag 2'], - threat: [], - type: 'query', - to: 'now', - note: '', - enabled: true, - created_by: 'sample user', - updated_by: 'sample user', - version: 1, - updated_at: ruleSO.updated_at ?? '', - created_at: ruleSO.attributes.createdAt, - throttle: 'no_actions', - exceptions_list: getListArrayMock(), - }); + expect(rule).toEqual(expectedRule()); }); test('builds a rule using rule SO and removes internal tags', () => { @@ -360,42 +331,110 @@ describe('buildRuleWithoutOverrides', () => { `${INTERNAL_IMMUTABLE_KEY}:true`, ]; const rule = buildRuleWithoutOverrides(ruleSO); - expect(rule).toEqual({ - actions: [], - author: ['Elastic'], - building_block_type: 'default', - id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - rule_id: 'rule-1', - false_positives: [], - max_signals: 10000, - risk_score: 50, - risk_score_mapping: [], - output_index: '.siem-signals', - description: 'Detecting root and admin users', - from: 'now-6m', - immutable: false, - index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - interval: '5m', - language: 'kuery', - license: 'Elastic License', - name: 'rule-name', - query: 'user.name: root or user.name: admin', - references: ['http://google.com'], - severity: 'high', - severity_mapping: [], - tags: ['some fake tag 1', 'some fake tag 2'], - threat: [], - type: 'query', - to: 'now', - note: '', - enabled: true, - created_by: 'sample user', - updated_by: 'sample user', - version: 1, - updated_at: ruleSO.updated_at ?? '', - created_at: ruleSO.attributes.createdAt, - throttle: 'no_actions', - exceptions_list: getListArrayMock(), - }); + expect(rule).toEqual(expectedRule()); + }); +}); + +describe('buildRuleWithOverrides', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('it builds a rule as expected with filters present', () => { + const ruleSO = sampleRuleSO(); + ruleSO.attributes.params.filters = [ + { + query: 'host.name: Rebecca', + }, + { + query: 'host.name: Evan', + }, + { + query: 'host.name: Braden', + }, + ]; + const rule = buildRuleWithOverrides(ruleSO, sampleDocNoSortId()._source); + const expected: RulesSchema = { + ...expectedRule(), + filters: ruleSO.attributes.params.filters, + }; + expect(rule).toEqual(expected); + }); + + test('it builds a rule and removes internal tags', () => { + const ruleSO = sampleRuleSO(); + ruleSO.attributes.tags = [ + 'some fake tag 1', + 'some fake tag 2', + `${INTERNAL_RULE_ID_KEY}:rule-1`, + `${INTERNAL_IMMUTABLE_KEY}:true`, + ]; + const rule = buildRuleWithOverrides(ruleSO, sampleDocNoSortId()._source); + expect(rule).toEqual(expectedRule()); + }); + + test('it applies rule name override in buildRule', () => { + const ruleSO = sampleRuleSO(); + ruleSO.attributes.params.ruleNameOverride = 'someKey'; + const rule = buildRuleWithOverrides(ruleSO, sampleDocNoSortId()._source); + const expected = { + ...expectedRule(), + name: 'someValue', + rule_name_override: 'someKey', + meta: { + ruleNameOverridden: true, + }, + }; + expect(rule).toEqual(expected); + }); + + test('it applies risk score override in buildRule', () => { + const newRiskScore = 79; + const ruleSO = sampleRuleSO(); + ruleSO.attributes.params.riskScoreMapping = [ + { + field: 'new_risk_score', + // value and risk_score aren't used for anything but are required in the schema + value: '', + operator: 'equals', + risk_score: undefined, + }, + ]; + const doc = sampleDocNoSortId(); + doc._source.new_risk_score = newRiskScore; + const rule = buildRuleWithOverrides(ruleSO, doc._source); + const expected = { + ...expectedRule(), + risk_score: newRiskScore, + risk_score_mapping: ruleSO.attributes.params.riskScoreMapping, + meta: { + riskScoreOverridden: true, + }, + }; + expect(rule).toEqual(expected); + }); + + test('it applies severity override in buildRule', () => { + const eventSeverity = '42'; + const ruleSO = sampleRuleSO(); + ruleSO.attributes.params.severityMapping = [ + { + field: 'event.severity', + value: eventSeverity, + operator: 'equals', + severity: 'critical', + }, + ]; + const doc = sampleDocSeverity(Number(eventSeverity)); + const rule = buildRuleWithOverrides(ruleSO, doc._source); + const expected = { + ...expectedRule(), + severity: 'critical', + severity_mapping: ruleSO.attributes.params.severityMapping, + meta: { + severityOverrideField: 'event.severity', + }, + }; + expect(rule).toEqual(expected); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts index e5370735333bc7..344f705c4af24e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts @@ -9,7 +9,7 @@ import { RulesSchema } from '../../../../common/detection_engine/schemas/respons import { RuleAlertAction } from '../../../../common/detection_engine/types'; import { RuleTypeParams } from '../types'; import { buildRiskScoreFromMapping } from './mappings/build_risk_score_from_mapping'; -import { SignalSourceHit, RuleAlertAttributes } from './types'; +import { SignalSourceHit, RuleAlertAttributes, SignalSource } from './types'; import { buildSeverityFromMapping } from './mappings/build_severity_from_mapping'; import { buildRuleNameFromMapping } from './mappings/build_rule_name_from_mapping'; import { INTERNAL_IDENTIFIER } from '../../../../common/constants'; @@ -46,19 +46,19 @@ export const buildRule = ({ throttle, }: BuildRuleParams): RulesSchema => { const { riskScore, riskScoreMeta } = buildRiskScoreFromMapping({ - doc, + eventSource: doc._source, riskScore: ruleParams.riskScore, riskScoreMapping: ruleParams.riskScoreMapping, }); const { severity, severityMeta } = buildSeverityFromMapping({ - doc, + eventSource: doc._source, severity: ruleParams.severity, severityMapping: ruleParams.severityMapping, }); const { ruleName, ruleNameMeta } = buildRuleNameFromMapping({ - doc, + eventSource: doc._source, ruleName: name, ruleNameMapping: ruleParams.ruleNameOverride, }); @@ -132,7 +132,7 @@ export const buildRuleWithoutOverrides = ( meta: ruleParams.meta, max_signals: ruleParams.maxSignals, risk_score: ruleParams.riskScore, - risk_score_mapping: ruleParams.riskScoreMapping ?? [], + risk_score_mapping: [], output_index: ruleParams.outputIndex, description: ruleParams.description, note: ruleParams.note, @@ -145,9 +145,8 @@ export const buildRuleWithoutOverrides = ( name: ruleSO.attributes.name, query: ruleParams.query, references: ruleParams.references, - rule_name_override: ruleParams.ruleNameOverride, severity: ruleParams.severity, - severity_mapping: ruleParams.severityMapping ?? [], + severity_mapping: [], tags: ruleSO.attributes.tags, type: ruleParams.type, to: ruleParams.to, @@ -184,3 +183,47 @@ export const removeInternalTagsFromRule = (rule: RulesSchema): RulesSchema => { return ruleWithoutInternalTags; } }; + +export const buildRuleWithOverrides = ( + ruleSO: SavedObject, + eventSource: SignalSource +): RulesSchema => { + const ruleWithoutOverrides = buildRuleWithoutOverrides(ruleSO); + return applyRuleOverrides(ruleWithoutOverrides, eventSource, ruleSO.attributes.params); +}; + +export const applyRuleOverrides = ( + rule: RulesSchema, + eventSource: SignalSource, + ruleParams: RuleTypeParams +): RulesSchema => { + const { riskScore, riskScoreMeta } = buildRiskScoreFromMapping({ + eventSource, + riskScore: ruleParams.riskScore, + riskScoreMapping: ruleParams.riskScoreMapping, + }); + + const { severity, severityMeta } = buildSeverityFromMapping({ + eventSource, + severity: ruleParams.severity, + severityMapping: ruleParams.severityMapping, + }); + + const { ruleName, ruleNameMeta } = buildRuleNameFromMapping({ + eventSource, + ruleName: rule.name, + ruleNameMapping: ruleParams.ruleNameOverride, + }); + + const meta = { ...ruleParams.meta, ...riskScoreMeta, ...severityMeta, ...ruleNameMeta }; + return { + ...rule, + risk_score: riskScore, + risk_score_mapping: ruleParams.riskScoreMapping ?? [], + severity, + severity_mapping: ruleParams.severityMapping ?? [], + name: ruleName, + rule_name_override: ruleParams.ruleNameOverride, + meta: Object.keys(meta).length > 0 ? meta : undefined, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts index e1d9c7f7c8a5ca..ff50c2634dfd16 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts @@ -14,7 +14,7 @@ describe('buildRiskScoreFromMapping', () => { test('risk score defaults to provided if mapping is incomplete', () => { const riskScore = buildRiskScoreFromMapping({ - doc: sampleDocNoSortId(), + eventSource: sampleDocNoSortId()._source, riskScore: 57, riskScoreMapping: undefined, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts index 888642f77af60c..c358339e66cd92 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts @@ -9,10 +9,10 @@ import { RiskScore, RiskScoreMappingOrUndefined, } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { SignalSourceHit } from '../types'; +import { SignalSource } from '../types'; interface BuildRiskScoreFromMappingProps { - doc: SignalSourceHit; + eventSource: SignalSource; riskScore: RiskScore; riskScoreMapping: RiskScoreMappingOrUndefined; } @@ -23,7 +23,7 @@ interface BuildRiskScoreFromMappingReturn { } export const buildRiskScoreFromMapping = ({ - doc, + eventSource, riskScore, riskScoreMapping, }: BuildRiskScoreFromMappingProps): BuildRiskScoreFromMappingReturn => { @@ -31,7 +31,7 @@ export const buildRiskScoreFromMapping = ({ if (riskScoreMapping != null && riskScoreMapping.length > 0) { const mappedField = riskScoreMapping[0].field; // TODO: Expand by verifying fieldType from index via doc._index - const mappedValue = get(mappedField, doc._source); + const mappedValue = get(mappedField, eventSource); if ( typeof mappedValue === 'number' && Number.isSafeInteger(mappedValue) && diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.test.ts index b509020646d1b5..b88a628b9735c2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.test.ts @@ -14,7 +14,7 @@ describe('buildRuleNameFromMapping', () => { test('rule name defaults to provided if mapping is incomplete', () => { const ruleName = buildRuleNameFromMapping({ - doc: sampleDocNoSortId(), + eventSource: sampleDocNoSortId()._source, ruleName: 'rule-name', ruleNameMapping: 'message', }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts index af540ed1454adf..c12baa556a7ff3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts @@ -10,10 +10,10 @@ import { Name, RuleNameOverrideOrUndefined, } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { SignalSourceHit } from '../types'; +import { SignalSource } from '../types'; interface BuildRuleNameFromMappingProps { - doc: SignalSourceHit; + eventSource: SignalSource; ruleName: Name; ruleNameMapping: RuleNameOverrideOrUndefined; } @@ -24,13 +24,13 @@ interface BuildRuleNameFromMappingReturn { } export const buildRuleNameFromMapping = ({ - doc, + eventSource, ruleName, ruleNameMapping, }: BuildRuleNameFromMappingProps): BuildRuleNameFromMappingReturn => { if (ruleNameMapping != null) { // TODO: Expand by verifying fieldType from index via doc._index - const mappedValue = get(ruleNameMapping, doc._source); + const mappedValue = get(ruleNameMapping, eventSource); if (t.string.is(mappedValue)) { return { ruleName: mappedValue, ruleNameMeta: { ruleNameOverridden: true } }; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts index fb1d51364ab393..430564cd985c2e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts @@ -14,7 +14,7 @@ describe('buildSeverityFromMapping', () => { test('severity defaults to provided if mapping is undefined', () => { const severity = buildSeverityFromMapping({ - doc: sampleDocNoSortId(), + eventSource: sampleDocNoSortId()._source, severity: 'low', severityMapping: undefined, }); @@ -24,7 +24,7 @@ describe('buildSeverityFromMapping', () => { test('severity is overridden to highest matched mapping', () => { const severity = buildSeverityFromMapping({ - doc: sampleDocSeverity(23), + eventSource: sampleDocSeverity(23)._source, severity: 'low', severityMapping: [ { field: 'event.severity', operator: 'equals', value: '23', severity: 'critical' }, @@ -44,7 +44,7 @@ describe('buildSeverityFromMapping', () => { test('severity is overridden when field is event.severity and source value is number', () => { const severity = buildSeverityFromMapping({ - doc: sampleDocSeverity(23), + eventSource: sampleDocSeverity(23)._source, severity: 'low', severityMapping: [ { field: 'event.severity', operator: 'equals', value: '13', severity: 'low' }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts index c0a62a2cc887d2..52ebd67f257af6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts @@ -11,10 +11,10 @@ import { severity as SeverityIOTS, SeverityMappingOrUndefined, } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { SignalSourceHit } from '../types'; +import { SignalSource } from '../types'; interface BuildSeverityFromMappingProps { - doc: SignalSourceHit; + eventSource: SignalSource; severity: Severity; severityMapping: SeverityMappingOrUndefined; } @@ -32,7 +32,7 @@ const severitySortMapping = { }; export const buildSeverityFromMapping = ({ - doc, + eventSource, severity, severityMapping, }: BuildSeverityFromMappingProps): BuildSeverityFromMappingReturn => { @@ -45,7 +45,7 @@ export const buildSeverityFromMapping = ({ ); severityMappingSorted.forEach((mapping) => { - const docValue = get(mapping.field, doc._source); + const docValue = get(mapping.field, eventSource); // TODO: Expand by verifying fieldType from index via doc._index // Till then, explicit parsing of event.severity (long) to number. If not ECS, this could be // another datatype, but until we can lookup datatype we must assume number for the Elastic diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts index a3b37270e50b1a..2eee1c18cd4c40 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts @@ -455,7 +455,7 @@ export const signalRulesAlertType = ({ ); } else if (response.hits.events !== undefined) { newSignals = response.hits.events.map((event) => - wrapSignal(buildSignalFromEvent(event, savedObject), outputIndex) + wrapSignal(buildSignalFromEvent(event, savedObject, true), outputIndex) ); } else { throw new Error(