From ec6d4ce2ef152f7c6b133a0759f6420c2ea7e514 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Thu, 30 Mar 2023 18:35:30 -0400 Subject: [PATCH 01/16] adds max signal warning --- .../threat_mapping/create_threat_signals.ts | 7 ++----- .../server/lib/detection_engine/rule_types/ml/ml.ts | 6 ++++++ .../new_terms/create_new_terms_alert_type.ts | 5 +++++ .../query/alert_suppression/group_and_bulk_create.ts | 10 +++++++++- .../rule_types/threshold/find_threshold_signals.ts | 8 ++++++++ .../detection_engine/rule_types/threshold/threshold.ts | 3 ++- .../rule_types/utils/search_after_bulk_create.ts | 4 ++++ .../lib/detection_engine/rule_types/utils/utils.ts | 4 ++++ 8 files changed, 40 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index acfe38eaca34a5..af8555b27ecb92 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -27,6 +27,7 @@ import { getAllowedFieldsForTermQuery } from './get_allowed_fields_for_terms_que import { getEventCount, getEventList } from './get_event_count'; import { getMappingFilters } from './get_mapping_filters'; import { THREAT_PIT_KEEP_ALIVE } from '../../../../../../common/cti/constants'; +import { getMaxSignalsWarning } from '../../utils/utils'; export const createThreatSignals = async ({ alertId, @@ -107,11 +108,6 @@ export const createThreatSignals = async ({ ruleExecutionLogger.debug(`Total event count: ${eventCount}`); - // if (eventCount === 0) { - // ruleExecutionLogger.debug('Indicator matching rule has completed'); - // return results; - // } - let threatPitId: OpenPointInTimeResponse['id'] = ( await services.scopedClusterClient.asCurrentUser.openPointInTime({ index: threatIndex, @@ -171,6 +167,7 @@ export const createThreatSignals = async ({ `all successes are ${results.success}` ); if (results.createdSignalsCount >= params.maxSignals) { + results.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); ruleExecutionLogger.debug( `Indicator match has reached its max signals count ${params.maxSignals}. Additional documents not checked are ${documentCount}` ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts index c0fb5401bede82..10acc379f98695 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts @@ -24,6 +24,7 @@ import { addToSearchAfterReturn, createErrorsFromShard, createSearchAfterReturnType, + getMaxSignalsWarning, mergeReturns, } from '../utils/utils'; import type { SetupPlugins } from '../../../../plugin'; @@ -105,6 +106,11 @@ export const mlExecutor = async ({ exceptionFilter, }); + // Checking before filtering against lists to get original hits value + if (anomalyResults.hits.hits.length >= tuple.maxSignals) { + result.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + } + const [filteredAnomalyHits, _] = await filterEventsAgainstList({ listClient, ruleExecutionLogger, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index c4525de1b00b35..3dd45dd0989761 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -38,6 +38,7 @@ import { import { addToSearchAfterReturn, createSearchAfterReturnType, + getMaxSignalsWarning, getUnprocessedExceptionsWarnings, } from '../utils/utils'; import { createEnrichEventsFunction } from '../utils/enrichments'; @@ -302,6 +303,10 @@ export const createNewTermsAlertType = ( ruleExecutionLogger, }); + if (wrappedAlerts.length + result.createdSignalsCount > params.maxSignals) { + result.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + } + const bulkCreateResult = await bulkCreate( wrappedAlerts, params.maxSignals - result.createdSignalsCount, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts index 99f1901aad9f82..aad505b5058c85 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts @@ -19,7 +19,11 @@ import type { SearchAfterAndBulkCreateReturnType, SignalSource, } from '../../types'; -import { addToSearchAfterReturn, getUnprocessedExceptionsWarnings } from '../../utils/utils'; +import { + addToSearchAfterReturn, + getMaxSignalsWarning, + getUnprocessedExceptionsWarnings, +} from '../../utils/utils'; import type { SuppressionBuckets } from './wrap_suppressed_alerts'; import { wrapSuppressedAlerts } from './wrap_suppressed_alerts'; import { buildGroupByFieldAggregation } from './build_group_by_field_aggregation'; @@ -206,6 +210,10 @@ export const groupAndBulkCreate = async ({ return toReturn; } + if (buckets.length >= tuple.maxSignals) { + toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + } + const suppressionBuckets: SuppressionBuckets[] = buckets.map((bucket) => ({ event: bucket.topHits.hits.hits[0], count: bucket.doc_count, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts index 758fe7b161d685..0b6bf5140c87e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts @@ -30,6 +30,7 @@ import type { } from './types'; import { shouldFilterByCardinality } from './utils'; import type { IRuleExecutionLogForExecutors } from '../../rule_monitoring'; +import { getMaxSignalsWarning } from '../utils/utils'; interface FindThresholdSignalsParams { from: string; @@ -70,6 +71,7 @@ export const findThresholdSignals = async ({ buckets: ThresholdBucket[]; searchDurations: string[]; searchErrors: string[]; + warnings: string[]; }> => { // Leaf aggregations used below let sortKeys; @@ -78,6 +80,7 @@ export const findThresholdSignals = async ({ searchDurations: [], searchErrors: [], }; + const warnings: string[] = []; const includeCardinalityFilter = shouldFilterByCardinality(threshold); @@ -166,8 +169,13 @@ export const findThresholdSignals = async ({ } } + if (buckets.length >= maxSignals) { + warnings.push(getMaxSignalsWarning(maxSignals)); + } + return { buckets: buckets.slice(0, maxSignals), ...searchAfterResults, + warnings, }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts index 670b3e5011a29f..944622c75ca948 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts @@ -128,7 +128,7 @@ export const thresholdExecutor = async ({ }); // Look for new events over threshold - const { buckets, searchErrors, searchDurations } = await findThresholdSignals({ + const { buckets, searchErrors, searchDurations, warnings } = await findThresholdSignals({ inputIndexPattern: inputIndex, from: tuple.from.toISOString(), to: tuple.to.toISOString(), @@ -164,6 +164,7 @@ export const thresholdExecutor = async ({ result.errors.push(...previousSearchErrors); result.errors.push(...searchErrors); + result.warningMessages.push(...warnings); result.searchAfterTimes = searchDurations; const createdAlerts = createResult.createdItems.map((alert) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts index 78bead8d70ff63..f1a4652954661e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts @@ -19,6 +19,7 @@ import { mergeSearchResults, getSafeSortIds, addToSearchAfterReturn, + getMaxSignalsWarning, } from './utils'; import type { SearchAfterAndBulkCreateParams, SearchAfterAndBulkCreateReturnType } from '../types'; import { withSecuritySpan } from '../../../../utils/with_security_span'; @@ -136,6 +137,9 @@ export const searchAfterAndBulkCreate = async ({ // skip the call to bulk create and proceed to the next search_after, // if there is a sort id to continue the search_after with. if (includedEvents.length !== 0) { + if (toReturn.createdSignalsCount + includedEvents.length > tuple.maxSignals) { + toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + } // make sure we are not going to create more signals than maxSignals allows const limitedEvents = includedEvents.slice( 0, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts index 711db3dc1e601d..2af5adb1707777 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts @@ -953,3 +953,7 @@ export const getUnprocessedExceptionsWarnings = ( )}`; } }; + +export const getMaxSignalsWarning = (maxSignalsCount: number): string => { + return `max_signals value was hit, only the first ${maxSignalsCount} alerts were indexed. Rule may be missing signal data`; +}; From 605332fd8b1619e1db46b4db2f514374e4b59416 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Thu, 13 Apr 2023 14:04:55 -0400 Subject: [PATCH 02/16] makes more inclusive --- .../rule_types/utils/search_after_bulk_create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts index f1a4652954661e..05047c4c648866 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts @@ -137,7 +137,7 @@ export const searchAfterAndBulkCreate = async ({ // skip the call to bulk create and proceed to the next search_after, // if there is a sort id to continue the search_after with. if (includedEvents.length !== 0) { - if (toReturn.createdSignalsCount + includedEvents.length > tuple.maxSignals) { + if (toReturn.createdSignalsCount + includedEvents.length >= tuple.maxSignals) { toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); } // make sure we are not going to create more signals than maxSignals allows From dbee6f9f43f669b4d911a96baad15bbc7021cd2f Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Fri, 21 Apr 2023 21:29:14 -0400 Subject: [PATCH 03/16] updates from convo --- .../create_persistence_rule_type_wrapper.ts | 2 ++ .../threat_mapping/create_threat_signals.ts | 8 ++++++-- .../rule_types/ml/find_ml_signals.ts | 3 +++ .../lib/detection_engine/rule_types/ml/ml.ts | 4 ++-- .../new_terms/create_new_terms_alert_type.ts | 10 +++++----- .../build_group_by_field_aggregation.ts | 2 +- .../group_and_bulk_create.ts | 2 +- .../utils/search_after_bulk_create.ts | 19 ++++++++----------- 8 files changed, 28 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts index 9f10d7e537a9f4..5aed6c5a682637 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts @@ -124,6 +124,8 @@ export const createPersistenceRuleTypeWrapper: CreatePersistenceRuleTypeWrapper if (filteredAlerts.length === 0) { return { createdAlerts: [], errors: {}, alertsWereTruncated: false }; + } else if (maxAlerts === 0) { + return { createdAlerts: [], errors: {}, alertsWereTruncated: true }; } let enrichedAlerts = filteredAlerts; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index af8555b27ecb92..5ad8678ac42d16 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -5,9 +5,9 @@ * 2.0. */ -import chunk from 'lodash/fp/chunk'; import type { OpenPointInTimeResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { uniq, chunk } from 'lodash/fp'; import { getThreatList, getThreatListCount } from './get_threat_list'; import type { CreateThreatSignalsOptions, @@ -167,7 +167,11 @@ export const createThreatSignals = async ({ `all successes are ${results.success}` ); if (results.createdSignalsCount >= params.maxSignals) { - results.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + if (results.warningMessages.includes(getMaxSignalsWarning(params.maxSignals))) { + results.warningMessages = uniq(results.warningMessages); + } else { + results.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + } ruleExecutionLogger.debug( `Indicator match has reached its max signals count ${params.maxSignals}. Additional documents not checked are ${documentCount}` ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/find_ml_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/find_ml_signals.ts index fdb7317e85bfa4..38a21961bda554 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/find_ml_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/find_ml_signals.ts @@ -20,6 +20,7 @@ export const findMlSignals = async ({ anomalyThreshold, from, to, + maxSignals, exceptionFilter, }: { ml: MlPluginSetup; @@ -29,6 +30,7 @@ export const findMlSignals = async ({ anomalyThreshold: number; from: string; to: string; + maxSignals: number; exceptionFilter: Filter | undefined; }): Promise => { const { mlAnomalySearch } = ml.mlSystemProvider(request, savedObjectsClient); @@ -37,6 +39,7 @@ export const findMlSignals = async ({ threshold: anomalyThreshold, earliestMs: dateMath.parse(from)?.valueOf() ?? 0, latestMs: dateMath.parse(to)?.valueOf() ?? 0, + maxRecords: maxSignals, exceptionFilter, }; return getAnomalies(params, mlAnomalySearch); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts index 10acc379f98695..157d64955f87b5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts @@ -103,11 +103,11 @@ export const mlExecutor = async ({ anomalyThreshold: ruleParams.anomalyThreshold, from: tuple.from.toISOString(), to: tuple.to.toISOString(), + maxSignals: tuple.maxSignals, exceptionFilter, }); - // Checking before filtering against lists to get original hits value - if (anomalyResults.hits.hits.length >= tuple.maxSignals) { + if (anomalyResults.hits.total && anomalyResults.hits.total > tuple.maxSignals) { result.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index 3dd45dd0989761..f1a7edae83e689 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -154,7 +154,7 @@ export const createNewTermsAlertType = ( // it's possible for the array to be truncated but alert documents could fail to be created for other reasons, // in which case createdSignalsCount would still be less than maxSignals. Since valid alerts were truncated from // the array in that case, we stop and report the errors. - while (result.createdSignalsCount < params.maxSignals) { + while (result.createdSignalsCount <= params.maxSignals) { // PHASE 1: Fetch a page of terms using a composite aggregation. This will collect a page from // all of the terms seen over the last rule interval. In the next phase we'll determine which // ones are new. @@ -303,10 +303,6 @@ export const createNewTermsAlertType = ( ruleExecutionLogger, }); - if (wrappedAlerts.length + result.createdSignalsCount > params.maxSignals) { - result.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); - } - const bulkCreateResult = await bulkCreate( wrappedAlerts, params.maxSignals - result.createdSignalsCount, @@ -316,6 +312,10 @@ export const createNewTermsAlertType = ( }) ); + if (bulkCreateResult.alertsWereTruncated) { + result.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + } + addToSearchAfterReturn({ current: result, next: bulkCreateResult }); if (bulkCreateResult.alertsWereTruncated) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/build_group_by_field_aggregation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/build_group_by_field_aggregation.ts index af0821de311468..8693d4aeecd735 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/build_group_by_field_aggregation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/build_group_by_field_aggregation.ts @@ -26,7 +26,7 @@ export const buildGroupByFieldAggregation = ({ }, }, })), - size: maxSignals, + size: maxSignals + 1, // Add extra bucket to check if there's more data after max signals }, aggs: { topHits: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts index aad505b5058c85..5c5b47e71fbd04 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts @@ -210,7 +210,7 @@ export const groupAndBulkCreate = async ({ return toReturn; } - if (buckets.length >= tuple.maxSignals) { + if (buckets.length > tuple.maxSignals) { toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts index 05047c4c648866..9a7a953cb9ed4c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts @@ -61,7 +61,7 @@ export const searchAfterAndBulkCreate = async ({ }); } - while (toReturn.createdSignalsCount < tuple.maxSignals) { + while (toReturn.createdSignalsCount <= tuple.maxSignals) { try { let mergedSearchResults = createSearchResultReturnType(); ruleExecutionLogger.debug(`sortIds: ${sortIds}`); @@ -137,26 +137,23 @@ export const searchAfterAndBulkCreate = async ({ // skip the call to bulk create and proceed to the next search_after, // if there is a sort id to continue the search_after with. if (includedEvents.length !== 0) { - if (toReturn.createdSignalsCount + includedEvents.length >= tuple.maxSignals) { - toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); - } - // make sure we are not going to create more signals than maxSignals allows - const limitedEvents = includedEvents.slice( - 0, - tuple.maxSignals - toReturn.createdSignalsCount - ); - const enrichedEvents = await enrichment(limitedEvents); + const enrichedEvents = await enrichment(includedEvents); const wrappedDocs = wrapHits(enrichedEvents, buildReasonMessage); const bulkCreateResult = await bulkCreate( wrappedDocs, - undefined, + tuple.maxSignals - toReturn.createdSignalsCount, createEnrichEventsFunction({ services, logger: ruleExecutionLogger, }) ); + if (bulkCreateResult.alertsWereTruncated) { + toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + break; + } + addToSearchAfterReturn({ current: toReturn, next: bulkCreateResult }); ruleExecutionLogger.debug(`created ${bulkCreateResult.createdItemsCount} signals`); From af1072e591252203c5c507f0c04bbad7b0433e71 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Fri, 21 Apr 2023 21:34:06 -0400 Subject: [PATCH 04/16] updates message --- .../indicator_match/threat_mapping/create_threat_signals.ts | 4 ++-- .../server/lib/detection_engine/rule_types/ml/ml.ts | 2 +- .../rule_types/new_terms/create_new_terms_alert_type.ts | 2 +- .../query/alert_suppression/group_and_bulk_create.ts | 2 +- .../rule_types/threshold/find_threshold_signals.ts | 2 +- .../rule_types/utils/search_after_bulk_create.ts | 2 +- .../server/lib/detection_engine/rule_types/utils/utils.ts | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index 5ad8678ac42d16..884ae9db1010c2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -167,10 +167,10 @@ export const createThreatSignals = async ({ `all successes are ${results.success}` ); if (results.createdSignalsCount >= params.maxSignals) { - if (results.warningMessages.includes(getMaxSignalsWarning(params.maxSignals))) { + if (results.warningMessages.includes(getMaxSignalsWarning())) { results.warningMessages = uniq(results.warningMessages); } else { - results.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + results.warningMessages.push(getMaxSignalsWarning()); } ruleExecutionLogger.debug( `Indicator match has reached its max signals count ${params.maxSignals}. Additional documents not checked are ${documentCount}` diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts index 157d64955f87b5..87095a1283f914 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts @@ -108,7 +108,7 @@ export const mlExecutor = async ({ }); if (anomalyResults.hits.total && anomalyResults.hits.total > tuple.maxSignals) { - result.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + result.warningMessages.push(getMaxSignalsWarning()); } const [filteredAnomalyHits, _] = await filterEventsAgainstList({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index f1a7edae83e689..6bf3afe78749c9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -313,7 +313,7 @@ export const createNewTermsAlertType = ( ); if (bulkCreateResult.alertsWereTruncated) { - result.warningMessages.push(getMaxSignalsWarning(params.maxSignals)); + result.warningMessages.push(getMaxSignalsWarning()); } addToSearchAfterReturn({ current: result, next: bulkCreateResult }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts index 5c5b47e71fbd04..4b666962d2f119 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts @@ -211,7 +211,7 @@ export const groupAndBulkCreate = async ({ } if (buckets.length > tuple.maxSignals) { - toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + toReturn.warningMessages.push(getMaxSignalsWarning()); } const suppressionBuckets: SuppressionBuckets[] = buckets.map((bucket) => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts index 0b6bf5140c87e7..bb99b2937d1b01 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts @@ -170,7 +170,7 @@ export const findThresholdSignals = async ({ } if (buckets.length >= maxSignals) { - warnings.push(getMaxSignalsWarning(maxSignals)); + warnings.push(getMaxSignalsWarning()); } return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts index 9a7a953cb9ed4c..8c7e71f75ace98 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.ts @@ -150,7 +150,7 @@ export const searchAfterAndBulkCreate = async ({ ); if (bulkCreateResult.alertsWereTruncated) { - toReturn.warningMessages.push(getMaxSignalsWarning(tuple.maxSignals)); + toReturn.warningMessages.push(getMaxSignalsWarning()); break; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts index 2af5adb1707777..0bb14b9df4b3b8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts @@ -954,6 +954,6 @@ export const getUnprocessedExceptionsWarnings = ( } }; -export const getMaxSignalsWarning = (maxSignalsCount: number): string => { - return `max_signals value was hit, only the first ${maxSignalsCount} alerts were indexed. Rule may be missing signal data`; +export const getMaxSignalsWarning = (): string => { + return `The max alerts circut breaker was hit but there might still be alerts this rule is missing`; }; From 4d86c88b51a54200676a251e607bda10beca3e84 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Sun, 23 Apr 2023 16:19:56 -0400 Subject: [PATCH 05/16] ups max signal count for testing --- .../utils/get_rule_for_signal_testing.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts index 321e821682878e..099c0f65150800 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts @@ -29,4 +29,5 @@ export const getRuleForSignalTesting = ( type: 'query', query: '*:*', from: '1900-01-01T00:00:00.000Z', + max_signals: 1000, }); From 5f00da8f635cd0d22d747612c5058df0586aabd6 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 24 Apr 2023 15:04:17 -0400 Subject: [PATCH 06/16] revert --- .../utils/get_rule_for_signal_testing.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts index 099c0f65150800..321e821682878e 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts @@ -29,5 +29,4 @@ export const getRuleForSignalTesting = ( type: 'query', query: '*:*', from: '1900-01-01T00:00:00.000Z', - max_signals: 1000, }); From 2ba57a7812b61437e394dd220e83a378bbec5186 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 24 Apr 2023 18:49:34 -0400 Subject: [PATCH 07/16] updates tests --- ...ld_group_by_field_aggregation.test.ts.snap | 2 +- .../basic/tests/open_close_signals.ts | 15 +++++++++++--- .../group1/check_privileges.ts | 5 ++++- .../group1/create_rules.ts | 14 +++++++++---- .../group1/create_rules_bulk.ts | 7 +++++-- .../group10/get_rule_execution_results.ts | 5 ++++- .../group10/open_close_signals.ts | 20 +++++++++++++++---- 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/__snapshots__/build_group_by_field_aggregation.test.ts.snap b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/__snapshots__/build_group_by_field_aggregation.test.ts.snap index a46533db938f35..415f423d21548b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/__snapshots__/build_group_by_field_aggregation.test.ts.snap +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/__snapshots__/build_group_by_field_aggregation.test.ts.snap @@ -29,7 +29,7 @@ Object { }, }, "composite": Object { - "size": 100, + "size": 101, "sources": Array [ Object { "host.name": Object { diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts index d7197d2372ea89..c67b9f098c3e3f 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts @@ -55,7 +55,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to execute and get 10 signals', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); @@ -64,7 +67,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be have set the signals in an open state initially', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); @@ -76,7 +82,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to get a count of 10 closed signals when closing 10', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts index edc1b8222b1833..b2057a8e719e92 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts @@ -58,7 +58,10 @@ export default ({ getService }: FtrProviderContext) => { ]; indexTestCases.forEach((index) => { it(`for KQL rule with index param: ${index}`, async () => { - const rule = getRuleForSignalTesting(index); + const rule = { + ...getRuleForSignalTesting(index), + query: 'process.executable: "/usr/bin/sudo"', + }; await createUserAndRole(getService, ROLES.detections_admin); const { id } = await createRuleWithAuth(supertestWithoutAuth, rule, { user: ROLES.detections_admin, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts index 4346087684fd49..7d125f0327f35c 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts @@ -111,11 +111,14 @@ export default ({ getService }: FtrProviderContext) => { this pops up again elsewhere. */ it('should create a single rule with a rule_id and validate it ran successfully', async () => { - const simpleRule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .send(simpleRule) + .send(rule) .expect(200); await waitForRuleSuccess({ supertest, log, id: body.id }); @@ -149,11 +152,14 @@ export default ({ getService }: FtrProviderContext) => { }); it('should create a single rule with a rule_id and an index pattern that does not match anything and an index pattern that does and the rule should be successful', async () => { - const simpleRule = getRuleForSignalTesting(['does-not-exist-*', 'auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['does-not-exist-*', 'auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .send(simpleRule) + .send(rule) .expect(200); await waitForRuleSuccess({ supertest, log, id: body.id }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules_bulk.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules_bulk.ts index 6d0e79975bfd68..67ce2ccf527600 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules_bulk.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules_bulk.ts @@ -102,11 +102,14 @@ export default ({ getService }: FtrProviderContext): void => { this pops up again elsewhere. */ it('should create a single rule with a rule_id and validate it ran successfully', async () => { - const simpleRule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { body } = await supertest .post(DETECTION_ENGINE_RULES_BULK_CREATE) .set('kbn-xsrf', 'true') - .send([simpleRule]) + .send([rule]) .expect(200); await waitForRuleSuccess({ supertest, log, id: body[0].id }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/get_rule_execution_results.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/get_rule_execution_results.ts index 0ba34e4987b2bf..369b661e83b692 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/get_rule_execution_results.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/get_rule_execution_results.ts @@ -72,7 +72,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return execution events for a rule that has executed successfully', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForEventLogExecuteComplete(es, log, id); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts index 93a4dd16393245..a6399cd7082af9 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts @@ -89,7 +89,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to execute and get 10 signals', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); @@ -98,7 +101,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be have set the signals in an open state initially', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); @@ -110,7 +116,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to get a count of 10 closed signals when closing 10', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); @@ -136,7 +145,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able close signals immediately and they all should be closed', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); From 74308d29e357e367ec17291cc79e44983e4b3d90 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 24 Apr 2023 21:19:55 -0400 Subject: [PATCH 08/16] updates remaining tests --- .../basic/tests/open_close_signals.ts | 5 ++++- .../group6/alerts/alerts_compatibility.ts | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts index c67b9f098c3e3f..ba2ca88f6f9dd7 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts @@ -111,7 +111,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able close 10 signals immediately and they all should be closed', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 10, [id]); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts index 7af3e0c00ed02f..635e9d20b7f41e 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts @@ -571,9 +571,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: SavedQueryRuleCreateProps = getSavedQueryRuleForSignalTesting([ - `.alerts-security.alerts-default`, - ]); + const rule: SavedQueryRuleCreateProps = { + ...getSavedQueryRuleForSignalTesting([`.alerts-security.alerts-default`]), + query: 'agent.name: "security-linux-1.example.dev"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); From 16f25761c33ad173edd29c200d1096792839be31 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 09:48:03 -0400 Subject: [PATCH 09/16] fixes tests --- x-pack/test/cases_api_integration/common/lib/alerts.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/test/cases_api_integration/common/lib/alerts.ts b/x-pack/test/cases_api_integration/common/lib/alerts.ts index 418c9f3c81bdab..9173416623d5d4 100644 --- a/x-pack/test/cases_api_integration/common/lib/alerts.ts +++ b/x-pack/test/cases_api_integration/common/lib/alerts.ts @@ -33,7 +33,10 @@ export const createSecuritySolutionAlerts = async ( supertest: SuperTest.SuperTest, log: ToolingLog ): Promise> => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); From 8d9b9eb3f7576cd5827aa1965ddd1c6ffe609ae9 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 13:14:46 -0400 Subject: [PATCH 10/16] adds new tests --- .../detection_engine/rule_types/eql/eql.ts | 4 +++ .../lib/detection_engine/rule_types/ml/ml.ts | 6 ++++- .../new_terms/create_new_terms_alert_type.ts | 5 +--- .../threshold/find_threshold_signals.ts | 2 +- .../tests/common/cases/patch_cases.ts | 20 +++++++++++--- .../rule_execution_logic/eql.ts | 9 +++++++ .../rule_execution_logic/machine_learning.ts | 17 ++++++++++++ .../rule_execution_logic/new_terms.ts | 27 +++++++++++++++++++ .../rule_execution_logic/query.ts | 19 +++++++++++++ .../rule_execution_logic/threat_match.ts | 7 +++++ .../rule_execution_logic/threshold.ts | 27 +++++++++++++++++++ 11 files changed, 133 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts index 492e555422e092..ecabf327f1ea12 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts @@ -30,6 +30,7 @@ import { createSearchAfterReturnType, makeFloatString, getUnprocessedExceptionsWarnings, + getMaxSignalsWarning, } from '../utils/utils'; import { buildReasonMessageForEqlAlert } from '../utils/reason_formatters'; import type { CompleteRule, EqlRuleParams } from '../../rule_schema'; @@ -130,6 +131,9 @@ export const eqlExecutor = async ({ addToSearchAfterReturn({ current: result, next: createResult }); } + if (result.createdSignalsCount >= ruleParams.maxSignals) { + result.warningMessages.push(getMaxSignalsWarning()); + } return result; }); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts index 87095a1283f914..0e937987ec5869 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/ml.ts @@ -107,7 +107,11 @@ export const mlExecutor = async ({ exceptionFilter, }); - if (anomalyResults.hits.total && anomalyResults.hits.total > tuple.maxSignals) { + if ( + anomalyResults.hits.total && + typeof anomalyResults.hits.total !== 'number' && + anomalyResults.hits.total.value > tuple.maxSignals + ) { result.warningMessages.push(getMaxSignalsWarning()); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index 6bf3afe78749c9..f3aea0e47a71f7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -312,13 +312,10 @@ export const createNewTermsAlertType = ( }) ); - if (bulkCreateResult.alertsWereTruncated) { - result.warningMessages.push(getMaxSignalsWarning()); - } - addToSearchAfterReturn({ current: result, next: bulkCreateResult }); if (bulkCreateResult.alertsWereTruncated) { + result.warningMessages.push(getMaxSignalsWarning()); break; } } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts index bb99b2937d1b01..e9d7b8901f9a6f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/find_threshold_signals.ts @@ -169,7 +169,7 @@ export const findThresholdSignals = async ({ } } - if (buckets.length >= maxSignals) { + if (buckets.length > maxSignals) { warnings.push(getMaxSignalsWarning()); } diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts index c8239ba02cd3f8..8f784d2e9c6976 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts @@ -800,7 +800,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('updates alert status when the status is updated and syncAlerts=true', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const postedCase = await createCase(supertest, postCaseReq); const { id } = await createRule(supertest, log, rule); @@ -856,7 +859,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('does NOT updates alert status when the status is updated and syncAlerts=false', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const postedCase = await createCase(supertest, { ...postCaseReq, @@ -909,7 +915,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('it updates alert status when syncAlerts is turned on', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const postedCase = await createCase(supertest, { ...postCaseReq, @@ -982,7 +991,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('it does NOT updates alert status when syncAlerts is turned off', async () => { - const rule = getRuleForSignalTesting(['auditbeat-*']); + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + }; const postedCase = await createCase(supertest, postCaseReq); const { id } = await createRule(supertest, log, rule); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/eql.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/eql.ts index ced077145f5a93..da33e0c0795f15 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/eql.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/eql.ts @@ -26,6 +26,7 @@ import { ALERT_ORIGINAL_EVENT_CATEGORY, ALERT_GROUP_ID, } from '@kbn/security-solution-plugin/common/field_maps/field_names'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { createRule, deleteAllRules, @@ -175,6 +176,14 @@ export default ({ getService }: FtrProviderContext) => { expect(previewAlerts.length).eql(maxSignals); }); + it('generates max signals warning when circuit breaker is hit', async () => { + const rule: EqlRuleCreateProps = { + ...getEqlRuleForSignalTesting(['auditbeat-*']), + }; + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).contain(getMaxSignalsWarning()); + }); + it('uses the provided event_category_override', async () => { const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts index 099104ad411f72..b68640bce3712f 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts @@ -23,6 +23,7 @@ import { ALERT_DEPTH, ALERT_ORIGINAL_TIME, } from '@kbn/security-solution-plugin/common/field_maps/field_names'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { expect } from 'expect'; import { createListsIndex, @@ -158,6 +159,22 @@ export default ({ getService }: FtrProviderContext) => { ); }); + it('generates max signals warning when circuit breaker is exceeded', async () => { + const { logs } = await previewRule({ + supertest, + rule: { ...rule, anomaly_threshold: 1, max_signals: 5 }, // This threshold generates 10 alerts with the current esArchive + }); + expect(logs[0].warnings).toContain(getMaxSignalsWarning()); + }); + + it("doesn't generate max signals warning when circuit breaker is met, but not exceeded", async () => { + const { logs } = await previewRule({ + supertest, + rule: { ...rule, anomaly_threshold: 1, max_signals: 10 }, + }); + expect(logs[0].warnings).not.toContain(getMaxSignalsWarning()); + }); + it('should create 7 alerts from ML rule when records meet anomaly_threshold', async () => { const { previewId } = await previewRule({ supertest, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/new_terms.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/new_terms.ts index 4a2aad16f70dfe..2b3afca22a33c8 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/new_terms.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/new_terms.ts @@ -15,6 +15,7 @@ import { getNewTermsRuntimeMappings, AGG_FIELD_NAME, } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/new_terms/utils'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { createRule, deleteAllRules, @@ -232,6 +233,32 @@ export default ({ getService }: FtrProviderContext) => { }); }); + it('generates max signals warning when circuit breaker is exceeded', async () => { + const rule: NewTermsRuleCreateProps = { + ...getCreateNewTermsRulesSchemaMock('rule-1', true), + new_terms_fields: ['process.pid'], + from: '2018-02-19T20:42:00.000Z', + // Set the history_window_start close to 'from' so we should alert on all terms in the time range + history_window_start: '2018-02-19T20:41:59.000Z', + }; + const { logs } = await previewRule({ supertest, rule }); + + expect(logs[0].warnings).contain(getMaxSignalsWarning()); + }); + + it("doesn't generate max signals warning when circuit breaker is met but not exceeded", async () => { + const rule: NewTermsRuleCreateProps = { + ...getCreateNewTermsRulesSchemaMock('rule-1', true), + new_terms_fields: ['host.ip'], + from: '2019-02-19T20:42:00.000Z', + history_window_start: '2019-01-19T20:42:00.000Z', + max_signals: 3, + }; + const { logs } = await previewRule({ supertest, rule }); + + expect(logs[0].warnings).not.contain(getMaxSignalsWarning()); + }); + it('should generate 3 alerts when 1 document has 3 new values', async () => { const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/query.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/query.ts index 3eb2db9ff5155b..6478a06b37d5e3 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/query.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/query.ts @@ -34,6 +34,7 @@ import { ALERT_ORIGINAL_EVENT, } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { DETECTION_ENGINE_SIGNALS_STATUS_URL } from '@kbn/security-solution-plugin/common/constants'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { deleteAllExceptions } from '../../../lists_api_integration/utils'; import { createExceptionList, @@ -104,6 +105,24 @@ export default ({ getService }: FtrProviderContext) => { expect(alerts.hits.hits[0]._source?.['kibana.alert.ancestors'][0].id).eql(ID); }); + it('generates max signals warning when circuit breaker is hit', async () => { + const rule: QueryRuleCreateProps = { + ...getRuleForSignalTesting(['auditbeat-*']), + }; + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).contain(getMaxSignalsWarning()); + }); + + it("doesn't generate max signals warning when circuit breaker is met but not exceeded", async () => { + const rule = { + ...getRuleForSignalTesting(['auditbeat-*']), + query: 'process.executable: "/usr/bin/sudo"', + max_signals: 10, + }; + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).not.contain(getMaxSignalsWarning()); + }); + it('should abide by max_signals > 100', async () => { const maxSignals = 200; const rule: QueryRuleCreateProps = { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts index 8b3e4db6fa5420..77e6e96d2985c9 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts @@ -34,6 +34,7 @@ import { ALERT_ORIGINAL_TIME, } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { previewRule, getOpenSignals, @@ -501,6 +502,12 @@ export default ({ getService }: FtrProviderContext) => { }); }); + it('generates max signals warning when circuit breaker is hit', async () => { + const rule: ThreatMatchRuleCreateProps = { ...createThreatMatchRule(), max_signals: 88 }; // Query generates 88 alerts with current esArchive + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).contain(getMaxSignalsWarning()); + }); + it('terms and match should have the same alerts with pagination', async () => { const termRule: ThreatMatchRuleCreateProps = createThreatMatchRule({ override: { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threshold.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threshold.ts index 3dc878c4e2ba0c..f9b2c7fff29620 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threshold.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threshold.ts @@ -21,6 +21,7 @@ import { ALERT_ORIGINAL_TIME, ALERT_THRESHOLD_RESULT, } from '@kbn/security-solution-plugin/common/field_maps/field_names'; +import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { createRule, getOpenSignals, @@ -93,6 +94,32 @@ export default ({ getService }: FtrProviderContext) => { }); }); + it('generates max signals warning when circuit breaker is exceeded', async () => { + const rule: ThresholdRuleCreateProps = { + ...getThresholdRuleForSignalTesting(['auditbeat-*']), + threshold: { + field: 'host.id', + value: 1, // This value generates 7 alerts with the current esArchive + }, + max_signals: 5, + }; + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).contain(getMaxSignalsWarning()); + }); + + it("doesn't generate max signals warning when circuit breaker is met but not exceeded", async () => { + const rule: ThresholdRuleCreateProps = { + ...getThresholdRuleForSignalTesting(['auditbeat-*']), + threshold: { + field: 'host.id', + value: 1, // This value generates 7 alerts with the current esArchive + }, + max_signals: 7, + }; + const { logs } = await previewRule({ supertest, rule }); + expect(logs[0].warnings).not.contain(getMaxSignalsWarning()); + }); + it('generates 2 signals from Threshold rules when threshold is met', async () => { const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), From 6facf8b192ef46f3714771a588c438c80eff12a3 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 15:22:06 -0400 Subject: [PATCH 11/16] adds comment --- .../query/alert_suppression/group_and_bulk_create.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts index 9e667117080666..fa139a9dfaf292 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts @@ -230,12 +230,11 @@ export const groupAndBulkCreate = async ({ return toReturn; } - if (buckets.length > tuple.maxSignals) { - if (toReturn.warningMessages.includes(getMaxSignalsWarning())) { - toReturn.warningMessages = uniq(toReturn.warningMessages); - } else { - toReturn.warningMessages.push(getMaxSignalsWarning()); - } + if ( + buckets.length > tuple.maxSignals && + !toReturn.warningMessages.includes(getMaxSignalsWarning()) // If the unsuppressed result didn't already hit max signals, we add the warning here + ) { + toReturn.warningMessages.push(getMaxSignalsWarning()); } const suppressionBuckets: SuppressionBucket[] = buckets.map((bucket) => ({ From 345ea57f581db245822e3e0db3722382bcd98b6f Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 16:20:51 -0400 Subject: [PATCH 12/16] removes old code --- .../rule_types/query/alert_suppression/group_and_bulk_create.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts index fa139a9dfaf292..b0120fa8466a8f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/alert_suppression/group_and_bulk_create.ts @@ -9,7 +9,6 @@ import type moment from 'moment'; import type * as estypes from '@elastic/elasticsearch/lib/api/types'; -import { uniq } from 'lodash/fp'; import { withSecuritySpan } from '../../../../../utils/with_security_span'; import { buildTimeRangeFilter } from '../../utils/build_events_query'; import type { RuleServices, RunOpts, SearchAfterAndBulkCreateReturnType } from '../../types'; From bff417913f1f4c139f6fa910d66c2621f33100e0 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 16:29:57 -0400 Subject: [PATCH 13/16] changes eql --- .../server/lib/detection_engine/rule_types/eql/eql.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts index ecabf327f1ea12..a55be51eca3a73 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/eql.ts @@ -131,7 +131,7 @@ export const eqlExecutor = async ({ addToSearchAfterReturn({ current: result, next: createResult }); } - if (result.createdSignalsCount >= ruleParams.maxSignals) { + if (response.hits.total && response.hits.total.value >= ruleParams.maxSignals) { result.warningMessages.push(getMaxSignalsWarning()); } return result; From 0116cd0174d36ab1f468ce3644de74f8c4fb7536 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 18:38:23 -0400 Subject: [PATCH 14/16] address comments --- .../indicator_match/threat_mapping/create_threat_signals.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index 884ae9db1010c2..7261147687e081 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -169,7 +169,7 @@ export const createThreatSignals = async ({ if (results.createdSignalsCount >= params.maxSignals) { if (results.warningMessages.includes(getMaxSignalsWarning())) { results.warningMessages = uniq(results.warningMessages); - } else { + } else if (documentCount > 0) { results.warningMessages.push(getMaxSignalsWarning()); } ruleExecutionLogger.debug( From 7680334496b043c50c3308fe16b542308d88dffd Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 18:49:47 -0400 Subject: [PATCH 15/16] changes message --- .../server/lib/detection_engine/rule_types/utils/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts index 0bb14b9df4b3b8..7f3298b32139f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts @@ -955,5 +955,5 @@ export const getUnprocessedExceptionsWarnings = ( }; export const getMaxSignalsWarning = (): string => { - return `The max alerts circut breaker was hit but there might still be alerts this rule is missing`; + return `This rule reached the maximum alert limit for the rule execution. Some alerts were not created.`; }; From 282094f4e82239fa3e007afd5d1ebc93d1c1fa3e Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Apr 2023 21:26:24 -0400 Subject: [PATCH 16/16] fixes flaky test --- .../group6/alerts/alerts_compatibility.ts | 21 ++++++++++++------- .../rule_execution_logic/threat_match.ts | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts index 635e9d20b7f41e..353af49d7456ea 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts @@ -558,9 +558,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: SavedQueryRuleCreateProps = getSavedQueryRuleForSignalTesting([ - `.siem-signals-*`, - ]); + const rule: SavedQueryRuleCreateProps = { + ...getSavedQueryRuleForSignalTesting([`.siem-signals-*`]), + query: 'agent.name: "security-linux-1.example.dev"', + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); @@ -600,7 +601,11 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting(['.siem-signals-*']); + const rule: EqlRuleCreateProps = { + ...getEqlRuleForSignalTesting(['.siem-signals-*']), + query: 'any where agent.name == "security-linux-1.example.dev"', + max_signals: 1000, + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); @@ -611,9 +616,11 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting([ - `.alerts-security.alerts-default`, - ]); + const rule: EqlRuleCreateProps = { + ...getEqlRuleForSignalTesting([`.alerts-security.alerts-default`]), + query: 'any where agent.name == "security-linux-1.example.dev"', + max_signals: 1000, + }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); await waitForSignalsToBePresent(supertest, log, 1, [id]); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts index 77e6e96d2985c9..c381c216bbf71e 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/threat_match.ts @@ -503,7 +503,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates max signals warning when circuit breaker is hit', async () => { - const rule: ThreatMatchRuleCreateProps = { ...createThreatMatchRule(), max_signals: 88 }; // Query generates 88 alerts with current esArchive + const rule: ThreatMatchRuleCreateProps = { ...createThreatMatchRule(), max_signals: 87 }; // Query generates 88 alerts with current esArchive const { logs } = await previewRule({ supertest, rule }); expect(logs[0].warnings).contain(getMaxSignalsWarning()); });