From 567afc391178218133cd93ef51b189bd56cb7410 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Thu, 19 Aug 2021 15:06:17 +0200 Subject: [PATCH 1/9] Remove saved_query logic for getFilters --- .../signals/executors/query.ts | 2 - .../signals/executors/threshold.ts | 2 - .../signals/get_filter.test.ts | 65 ------------------- .../detection_engine/signals/get_filter.ts | 61 +---------------- .../threat_mapping/create_threat_signal.ts | 2 - 5 files changed, 3 insertions(+), 129 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts index f281475fe59eb..16850ef9690e1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts @@ -66,8 +66,6 @@ export const queryExecutor = async ({ filters: ruleParams.filters, language: ruleParams.language, query: ruleParams.query, - savedId: ruleParams.savedId, - services, index: inputIndex, lists: exceptionItems, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts index ffd90f3b90b91..79624ee7df828 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts @@ -103,8 +103,6 @@ export const thresholdExecutor = async ({ filters: ruleParams.filters ? ruleParams.filters.concat(bucketFilters) : bucketFilters, language: ruleParams.language, query: ruleParams.query, - savedId: ruleParams.savedId, - services, index: inputIndex, lists: exceptionItems, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts index 55cd7b942b3d8..ea75122eb78ef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts @@ -41,8 +41,6 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', - savedId: undefined, - services: servicesMock, index: ['auditbeat-*'], lists: [], }); @@ -76,8 +74,6 @@ describe('get_filter', () => { filters: undefined, language: undefined, query: 'host.name: siem', - savedId: undefined, - services: servicesMock, index: ['auditbeat-*'], lists: [], }) @@ -91,8 +87,6 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: undefined, - savedId: undefined, - services: servicesMock, index: ['auditbeat-*'], lists: [], }) @@ -106,67 +100,12 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', - savedId: undefined, - services: servicesMock, index: undefined, lists: [], }) ).rejects.toThrow('query, filters, and index parameter should be defined'); }); - test('returns a saved query if given a type of query', async () => { - const filter = await getFilter({ - type: 'saved_query', - filters: undefined, - language: undefined, - query: undefined, - savedId: 'some-id', - services: servicesMock, - index: ['auditbeat-*'], - lists: [], - }); - expect(filter).toEqual({ - bool: { - filter: [ - { bool: { minimum_should_match: 1, should: [{ match: { 'host.name': 'linux' } }] } }, - ], - must: [], - must_not: [], - should: [], - }, - }); - }); - - test('throws on saved query if saved_id is undefined', async () => { - await expect( - getFilter({ - type: 'saved_query', - filters: undefined, - language: undefined, - query: undefined, - savedId: undefined, - services: servicesMock, - index: ['auditbeat-*'], - lists: [], - }) - ).rejects.toThrow('savedId parameter should be defined'); - }); - - test('throws on saved query if index is undefined', async () => { - await expect( - getFilter({ - type: 'saved_query', - filters: undefined, - language: undefined, - query: undefined, - savedId: 'some-id', - services: servicesMock, - index: undefined, - lists: [], - }) - ).rejects.toThrow('savedId parameter should be defined'); - }); - test('throws on machine learning query', async () => { await expect( getFilter({ @@ -174,8 +113,6 @@ describe('get_filter', () => { filters: undefined, language: undefined, query: undefined, - savedId: 'some-id', - services: servicesMock, index: undefined, lists: [], }) @@ -188,8 +125,6 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', - savedId: undefined, - services: servicesMock, index: ['auditbeat-*'], lists: [getExceptionListItemSchemaMock()], }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index 346c4adeba537..f14fef49501fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -12,15 +12,8 @@ import { assertUnreachable } from '../../../../common/utility_types'; import { getQueryFilter } from '../../../../common/detection_engine/get_query_filter'; import { QueryOrUndefined, - SavedIdOrUndefined, IndexOrUndefined, } from '../../../../common/detection_engine/schemas/common/schemas'; -import { - AlertInstanceContext, - AlertInstanceState, - AlertServices, -} from '../../../../../alerting/server'; -import { PartialFilter } from '../types'; import { QueryFilter } from './types'; interface GetFilterArgs { @@ -28,27 +21,14 @@ interface GetFilterArgs { filters: unknown | undefined; language: LanguageOrUndefined; query: QueryOrUndefined; - savedId: SavedIdOrUndefined; - services: AlertServices; index: IndexOrUndefined; lists: ExceptionListItemSchema[]; } -interface QueryAttributes { - // NOTE: doesn't match Query interface - query: { - query: string; - language: Language; - }; - filters: PartialFilter[]; -} - export const getFilter = async ({ filters, index, language, - savedId, - services, type, query, lists, @@ -61,47 +41,12 @@ export const getFilter = async ({ } }; - const savedQueryFilter = async () => { - if (savedId != null && index != null) { - try { - // try to get the saved object first - const savedObject = await services.savedObjectsClient.get( - 'query', - savedId - ); - return getQueryFilter( - savedObject.attributes.query.query, - savedObject.attributes.query.language, - savedObject.attributes.filters, - index, - lists - ); - } catch (err) { - // saved object does not exist, so try and fall back if the user pushed - // any additional language, query, filters, etc... - if (query != null && language != null && index != null) { - return getQueryFilter(query, language, filters || [], index, lists); - } else { - // user did not give any additional fall back mechanism for generating a rule - // rethrow error for activity monitoring - throw err; - } - } - } else { - throw new BadRequestError('savedId parameter should be defined'); - } - }; - switch (type) { case 'threat_match': - case 'threshold': { - return savedId != null ? savedQueryFilter() : queryFilter(); - } - case 'query': { - return queryFilter(); - } + case 'threshold': + case 'query': case 'saved_query': { - return savedQueryFilter(); + return queryFilter(); } case 'machine_learning': { throw new BadRequestError( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts index 312d75f7a10cc..260847b679059 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts @@ -58,8 +58,6 @@ export const createThreatSignal = async ({ filters: [...filters, threatFilter], language, query, - savedId, - services, index: inputIndex, lists: exceptionItems, }); From 2fb24e9f2569605ef668fd51b0eb277086dd12db Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Thu, 19 Aug 2021 17:51:31 +0200 Subject: [PATCH 2/9] Fix types --- .../server/lib/detection_engine/signals/get_filter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index f14fef49501fb..b59a5fcc747fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -6,7 +6,7 @@ */ import { BadRequestError } from '@kbn/securitysolution-es-utils'; -import { Type, LanguageOrUndefined, Language } from '@kbn/securitysolution-io-ts-alerting-types'; +import { Type, LanguageOrUndefined } from '@kbn/securitysolution-io-ts-alerting-types'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { assertUnreachable } from '../../../../common/utility_types'; import { getQueryFilter } from '../../../../common/detection_engine/get_query_filter'; From 04cceaa96ea33c4cb468217a597e399bbeaea695 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Wed, 25 Aug 2021 14:03:25 +0200 Subject: [PATCH 3/9] Remove save id label from rule card description --- .../rules/description_step/helpers.test.tsx | 1 - .../components/rules/description_step/helpers.tsx | 11 +---------- .../rules/description_step/translations.tsx | 7 ------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx index e13f95e9d72ef..8de7e234bdd7a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx @@ -189,7 +189,6 @@ describe('helpers', () => { query: mockQueryBarWithSavedId.query, savedId: mockQueryBarWithSavedId.saved_id, }); - expect(result[0].title).toEqual(<>{i18n.SAVED_ID_LABEL} ); expect(result[0].description).toEqual(<>{mockQueryBarWithSavedId.saved_id} ); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx index 17162a2206fc3..f7d10b16e3899 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx @@ -65,7 +65,6 @@ export const buildQueryBarDescription = ({ filters, filterManager, query, - savedId, indexPatterns, queryLabel, }: BuildQueryBarDescription): ListItems[] => { @@ -106,15 +105,7 @@ export const buildQueryBarDescription = ({ }, ]; } - if (!isEmpty(savedId)) { - items = [ - ...items, - { - title: <>{i18n.SAVED_ID_LABEL} , - description: <>{savedId} , - }, - ]; - } + return items; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx index 1b0d906528b95..2da08a2374a3b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx @@ -28,13 +28,6 @@ export const THREAT_QUERY_LABEL = i18n.translate( } ); -export const SAVED_ID_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.savedIdLabel', - { - defaultMessage: 'Saved query name', - } -); - export const ML_TYPE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.mlRuleTypeDescription', { From 2ad42e7bc2e110133423be2b23b575b8a4de6a50 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Thu, 26 Aug 2021 16:35:31 +0200 Subject: [PATCH 4/9] Removed saved query creation when saved_id provided --- .../rules/description_step/helpers.test.tsx | 4 ++-- .../detection_engine/rules/create/helpers.test.ts | 14 +++++++------- .../pages/detection_engine/rules/create/helpers.ts | 2 -- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx index 8de7e234bdd7a..9cd98fafa8c62 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx @@ -176,7 +176,7 @@ describe('helpers', () => { ); }); - test('returns expected array of ListItems when "savedId" exists', () => { + test('returns empty array of ListItems when "savedId" exists', () => { const mockQueryBarWithSavedId = { ...mockQueryBar, query: '', @@ -189,7 +189,7 @@ describe('helpers', () => { query: mockQueryBarWithSavedId.query, savedId: mockQueryBarWithSavedId.saved_id, }); - expect(result[0].description).toEqual(<>{mockQueryBarWithSavedId.saved_id} ); + expect(result.length).toEqual(0); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts index f018bc148d626..b3b7ea3e29d1d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts @@ -120,7 +120,7 @@ describe('helpers', () => { query: 'test query', saved_id: 'test123', index: ['filebeat-'], - type: 'saved_query', + type: 'query', timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', timeline_title: 'Titled timeline', }; @@ -166,7 +166,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'saved_query', + type: 'query', }; expect(result).toEqual(expected); @@ -188,7 +188,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'saved_query', + type: 'query', timeline_id: '', timeline_title: 'Titled timeline', }; @@ -214,7 +214,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'saved_query', + type: 'query', }; expect(result).toEqual(expected); @@ -236,7 +236,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'saved_query', + type: 'query', timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', timeline_title: '', }; @@ -828,10 +828,10 @@ describe('helpers', () => { mockActions = mockActionsStepRule(); }); - test('returns rule with type of saved_query when saved_id exists', () => { + test('returns rule with type of query when saved_id exists', () => { const result = formatRule(mockDefine, mockAbout, mockSchedule, mockActions); - expect(result.type).toEqual('saved_query'); + expect(result.type).toEqual('query'); }); test('returns rule with type of query when saved_id does not exist', () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts index 44a85cb2028c0..041bf93665fab 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts @@ -256,8 +256,6 @@ export const formatDefineStepData = (defineStepData: DefineStepRule): DefineStep language: ruleFields.queryBar?.query?.language, query: ruleFields.queryBar?.query?.query as string, saved_id: ruleFields.queryBar?.saved_id, - ...(ruleType === 'query' && - ruleFields.queryBar?.saved_id && { type: 'saved_query' as Type }), }; return { From 3f9d3f09f350a25c634be06c8e35bd4c4da498d4 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Thu, 26 Aug 2021 16:38:07 +0200 Subject: [PATCH 5/9] Fix i18n --- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 2 files changed, 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 387f9110cc666..abae5baa87348 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20170,7 +20170,6 @@ "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "カスタムクエリ", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "クエリ", "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "次の一覧の問題を解決してください", - "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "保存されたクエリ名", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "説明が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "インデックスパターン", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "既存のエンドポイント例外をルールに追加", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f376d50889da1..43e11f2ae77f8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20636,7 +20636,6 @@ "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "定制查询", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "查询", "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "请修复下面所列的问题", - "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "已保存查询名称", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "描述必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "索引模式", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "将现有的终端例外添加到规则", From 8a0d58279928298d870176b9a3eddb665617a9d6 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Wed, 1 Sep 2021 13:31:52 +0200 Subject: [PATCH 6/9] Revert Saved query and saved_id removing This reverts commit 3f9d3f09f350a25c634be06c8e35bd4c4da498d4 2fb24e9f2569605ef668fd51b0eb277086dd12db. 2ad42e7bc2e110133423be2b23b575b8a4de6a50 04cceaa96ea33c4cb468217a597e399bbeaea695 --- .../rules/description_step/helpers.test.tsx | 5 +++-- .../components/rules/description_step/helpers.tsx | 11 ++++++++++- .../rules/description_step/translations.tsx | 7 +++++++ .../detection_engine/rules/create/helpers.test.ts | 14 +++++++------- .../pages/detection_engine/rules/create/helpers.ts | 2 ++ .../lib/detection_engine/signals/get_filter.ts | 2 +- .../plugins/translations/translations/ja-JP.json | 1 + .../plugins/translations/translations/zh-CN.json | 1 + 8 files changed, 32 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx index 9cd98fafa8c62..e13f95e9d72ef 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx @@ -176,7 +176,7 @@ describe('helpers', () => { ); }); - test('returns empty array of ListItems when "savedId" exists', () => { + test('returns expected array of ListItems when "savedId" exists', () => { const mockQueryBarWithSavedId = { ...mockQueryBar, query: '', @@ -189,7 +189,8 @@ describe('helpers', () => { query: mockQueryBarWithSavedId.query, savedId: mockQueryBarWithSavedId.saved_id, }); - expect(result.length).toEqual(0); + expect(result[0].title).toEqual(<>{i18n.SAVED_ID_LABEL} ); + expect(result[0].description).toEqual(<>{mockQueryBarWithSavedId.saved_id} ); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx index f7d10b16e3899..17162a2206fc3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx @@ -65,6 +65,7 @@ export const buildQueryBarDescription = ({ filters, filterManager, query, + savedId, indexPatterns, queryLabel, }: BuildQueryBarDescription): ListItems[] => { @@ -105,7 +106,15 @@ export const buildQueryBarDescription = ({ }, ]; } - + if (!isEmpty(savedId)) { + items = [ + ...items, + { + title: <>{i18n.SAVED_ID_LABEL} , + description: <>{savedId} , + }, + ]; + } return items; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx index 2da08a2374a3b..1b0d906528b95 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/translations.tsx @@ -28,6 +28,13 @@ export const THREAT_QUERY_LABEL = i18n.translate( } ); +export const SAVED_ID_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.savedIdLabel', + { + defaultMessage: 'Saved query name', + } +); + export const ML_TYPE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.mlRuleTypeDescription', { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts index b3b7ea3e29d1d..f018bc148d626 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts @@ -120,7 +120,7 @@ describe('helpers', () => { query: 'test query', saved_id: 'test123', index: ['filebeat-'], - type: 'query', + type: 'saved_query', timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', timeline_title: 'Titled timeline', }; @@ -166,7 +166,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'query', + type: 'saved_query', }; expect(result).toEqual(expected); @@ -188,7 +188,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'query', + type: 'saved_query', timeline_id: '', timeline_title: 'Titled timeline', }; @@ -214,7 +214,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'query', + type: 'saved_query', }; expect(result).toEqual(expected); @@ -236,7 +236,7 @@ describe('helpers', () => { query: 'test query', index: ['filebeat-'], saved_id: 'test123', - type: 'query', + type: 'saved_query', timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', timeline_title: '', }; @@ -828,10 +828,10 @@ describe('helpers', () => { mockActions = mockActionsStepRule(); }); - test('returns rule with type of query when saved_id exists', () => { + test('returns rule with type of saved_query when saved_id exists', () => { const result = formatRule(mockDefine, mockAbout, mockSchedule, mockActions); - expect(result.type).toEqual('query'); + expect(result.type).toEqual('saved_query'); }); test('returns rule with type of query when saved_id does not exist', () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts index 041bf93665fab..44a85cb2028c0 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts @@ -256,6 +256,8 @@ export const formatDefineStepData = (defineStepData: DefineStepRule): DefineStep language: ruleFields.queryBar?.query?.language, query: ruleFields.queryBar?.query?.query as string, saved_id: ruleFields.queryBar?.saved_id, + ...(ruleType === 'query' && + ruleFields.queryBar?.saved_id && { type: 'saved_query' as Type }), }; return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index b59a5fcc747fb..f14fef49501fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -6,7 +6,7 @@ */ import { BadRequestError } from '@kbn/securitysolution-es-utils'; -import { Type, LanguageOrUndefined } from '@kbn/securitysolution-io-ts-alerting-types'; +import { Type, LanguageOrUndefined, Language } from '@kbn/securitysolution-io-ts-alerting-types'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { assertUnreachable } from '../../../../common/utility_types'; import { getQueryFilter } from '../../../../common/detection_engine/get_query_filter'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index db4be304e7613..1350b9d799a7c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20123,6 +20123,7 @@ "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "カスタムクエリ", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "クエリ", "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "次の一覧の問題を解決してください", + "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "保存されたクエリ名", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "説明が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "インデックスパターン", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "既存のエンドポイント例外をルールに追加", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d2e91a87b5573..85889a4094036 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20589,6 +20589,7 @@ "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "定制查询", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "查询", "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "请修复下面所列的问题", + "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "已保存查询名称", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "描述必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "索引模式", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "将现有的终端例外添加到规则", From 8135adcabda0efa89bee09819bea91b445ef4723 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Wed, 1 Sep 2021 13:37:01 +0200 Subject: [PATCH 7/9] Revert "Remove saved_query logic for getFilters" This reverts commit 567afc391178218133cd93ef51b189bd56cb7410. --- .../signals/executors/query.ts | 2 + .../signals/executors/threshold.ts | 2 + .../signals/get_filter.test.ts | 65 +++++++++++++++++++ .../detection_engine/signals/get_filter.ts | 61 ++++++++++++++++- .../threat_mapping/create_threat_signal.ts | 2 + 5 files changed, 129 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts index 16850ef9690e1..f281475fe59eb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts @@ -66,6 +66,8 @@ export const queryExecutor = async ({ filters: ruleParams.filters, language: ruleParams.language, query: ruleParams.query, + savedId: ruleParams.savedId, + services, index: inputIndex, lists: exceptionItems, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts index 79624ee7df828..ffd90f3b90b91 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts @@ -103,6 +103,8 @@ export const thresholdExecutor = async ({ filters: ruleParams.filters ? ruleParams.filters.concat(bucketFilters) : bucketFilters, language: ruleParams.language, query: ruleParams.query, + savedId: ruleParams.savedId, + services, index: inputIndex, lists: exceptionItems, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts index ea75122eb78ef..55cd7b942b3d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts @@ -41,6 +41,8 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', + savedId: undefined, + services: servicesMock, index: ['auditbeat-*'], lists: [], }); @@ -74,6 +76,8 @@ describe('get_filter', () => { filters: undefined, language: undefined, query: 'host.name: siem', + savedId: undefined, + services: servicesMock, index: ['auditbeat-*'], lists: [], }) @@ -87,6 +91,8 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: undefined, + savedId: undefined, + services: servicesMock, index: ['auditbeat-*'], lists: [], }) @@ -100,12 +106,67 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', + savedId: undefined, + services: servicesMock, index: undefined, lists: [], }) ).rejects.toThrow('query, filters, and index parameter should be defined'); }); + test('returns a saved query if given a type of query', async () => { + const filter = await getFilter({ + type: 'saved_query', + filters: undefined, + language: undefined, + query: undefined, + savedId: 'some-id', + services: servicesMock, + index: ['auditbeat-*'], + lists: [], + }); + expect(filter).toEqual({ + bool: { + filter: [ + { bool: { minimum_should_match: 1, should: [{ match: { 'host.name': 'linux' } }] } }, + ], + must: [], + must_not: [], + should: [], + }, + }); + }); + + test('throws on saved query if saved_id is undefined', async () => { + await expect( + getFilter({ + type: 'saved_query', + filters: undefined, + language: undefined, + query: undefined, + savedId: undefined, + services: servicesMock, + index: ['auditbeat-*'], + lists: [], + }) + ).rejects.toThrow('savedId parameter should be defined'); + }); + + test('throws on saved query if index is undefined', async () => { + await expect( + getFilter({ + type: 'saved_query', + filters: undefined, + language: undefined, + query: undefined, + savedId: 'some-id', + services: servicesMock, + index: undefined, + lists: [], + }) + ).rejects.toThrow('savedId parameter should be defined'); + }); + test('throws on machine learning query', async () => { await expect( getFilter({ @@ -113,6 +174,8 @@ describe('get_filter', () => { filters: undefined, language: undefined, query: undefined, + savedId: 'some-id', + services: servicesMock, index: undefined, lists: [], }) @@ -125,6 +188,8 @@ describe('get_filter', () => { filters: undefined, language: 'kuery', query: 'host.name: siem', + savedId: undefined, + services: servicesMock, index: ['auditbeat-*'], lists: [getExceptionListItemSchemaMock()], }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index f14fef49501fb..346c4adeba537 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -12,8 +12,15 @@ import { assertUnreachable } from '../../../../common/utility_types'; import { getQueryFilter } from '../../../../common/detection_engine/get_query_filter'; import { QueryOrUndefined, + SavedIdOrUndefined, IndexOrUndefined, } from '../../../../common/detection_engine/schemas/common/schemas'; +import { + AlertInstanceContext, + AlertInstanceState, + AlertServices, +} from '../../../../../alerting/server'; +import { PartialFilter } from '../types'; import { QueryFilter } from './types'; interface GetFilterArgs { @@ -21,14 +28,27 @@ interface GetFilterArgs { filters: unknown | undefined; language: LanguageOrUndefined; query: QueryOrUndefined; + savedId: SavedIdOrUndefined; + services: AlertServices; index: IndexOrUndefined; lists: ExceptionListItemSchema[]; } +interface QueryAttributes { + // NOTE: doesn't match Query interface + query: { + query: string; + language: Language; + }; + filters: PartialFilter[]; +} + export const getFilter = async ({ filters, index, language, + savedId, + services, type, query, lists, @@ -41,13 +61,48 @@ export const getFilter = async ({ } }; + const savedQueryFilter = async () => { + if (savedId != null && index != null) { + try { + // try to get the saved object first + const savedObject = await services.savedObjectsClient.get( + 'query', + savedId + ); + return getQueryFilter( + savedObject.attributes.query.query, + savedObject.attributes.query.language, + savedObject.attributes.filters, + index, + lists + ); + } catch (err) { + // saved object does not exist, so try and fall back if the user pushed + // any additional language, query, filters, etc... + if (query != null && language != null && index != null) { + return getQueryFilter(query, language, filters || [], index, lists); + } else { + // user did not give any additional fall back mechanism for generating a rule + // rethrow error for activity monitoring + throw err; + } + } + } else { + throw new BadRequestError('savedId parameter should be defined'); + } + }; + switch (type) { case 'threat_match': - case 'threshold': - case 'query': - case 'saved_query': { + case 'threshold': { + return savedId != null ? savedQueryFilter() : queryFilter(); + } + case 'query': { return queryFilter(); } + case 'saved_query': { + return savedQueryFilter(); + } case 'machine_learning': { throw new BadRequestError( 'Unsupported Rule of type "machine_learning" supplied to getFilter' diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts index cf93f3ffa847e..33ba4723d82b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signal.ts @@ -58,6 +58,8 @@ export const createThreatSignal = async ({ filters: [...filters, threatFilter], language, query, + savedId, + services, index: inputIndex, lists: exceptionItems, }); From 7f45d6fa096484e8e1f9bdf151f15ce1ce922e31 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Wed, 1 Sep 2021 14:03:31 +0200 Subject: [PATCH 8/9] Ignore saved_id for Threat match and threshold rules --- .../signals/get_filter.test.ts | 46 +++++++++++++++++++ .../detection_engine/signals/get_filter.ts | 4 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts index 55cd7b942b3d8..5cce612076c99 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts @@ -137,6 +137,52 @@ describe('get_filter', () => { }); }); + test('return query for threat_match rule, despite saved_id is specify', async () => { + const filter = await getFilter({ + type: 'threat_match', + filters: undefined, + language: 'kuery', + query: 'host.name: siem', + savedId: 'some-id', + services: servicesMock, + index: ['auditbeat-*'], + lists: [], + }); + expect(filter).toEqual({ + bool: { + filter: [ + { bool: { minimum_should_match: 1, should: [{ match: { 'host.name': 'siem' } }] } }, + ], + must: [], + must_not: [], + should: [], + }, + }); + }); + + test('return query for threshold rule, despite saved_id is specify', async () => { + const filter = await getFilter({ + type: 'threat_match', + filters: undefined, + language: 'kuery', + query: 'host.name: siem', + savedId: 'some-id', + services: servicesMock, + index: ['auditbeat-*'], + lists: [], + }); + expect(filter).toEqual({ + bool: { + filter: [ + { bool: { minimum_should_match: 1, should: [{ match: { 'host.name': 'siem' } }] } }, + ], + must: [], + must_not: [], + should: [], + }, + }); + }); + test('throws on saved query if saved_id is undefined', async () => { await expect( getFilter({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index 346c4adeba537..574020af45c15 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -94,9 +94,7 @@ export const getFilter = async ({ switch (type) { case 'threat_match': - case 'threshold': { - return savedId != null ? savedQueryFilter() : queryFilter(); - } + case 'threshold': case 'query': { return queryFilter(); } From ba0930104ef7f0d9c3fad9ef38529f460f17cbd2 Mon Sep 17 00:00:00 2001 From: Nikita Khristinin Date: Thu, 2 Sep 2021 16:22:15 +0200 Subject: [PATCH 9/9] Fix mesasge commit --- .../server/lib/detection_engine/signals/get_filter.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts index 5cce612076c99..49f70eafd7d3a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.test.ts @@ -137,7 +137,7 @@ describe('get_filter', () => { }); }); - test('return query for threat_match rule, despite saved_id is specify', async () => { + test('returns the query persisted to the threat_match rule, despite saved_id being specified', async () => { const filter = await getFilter({ type: 'threat_match', filters: undefined, @@ -160,7 +160,7 @@ describe('get_filter', () => { }); }); - test('return query for threshold rule, despite saved_id is specify', async () => { + test('returns the query persisted to the threshold rule, despite saved_id being specified', async () => { const filter = await getFilter({ type: 'threat_match', filters: undefined,