Skip to content

Commit

Permalink
[Security Solution][Detection Engine] fixes alert suppression for thr…
Browse files Browse the repository at this point in the history
…eshold rule when suppression value is a number (elastic#173093)

## Summary

- fixes rule execution failure, when one of the suppression values is
`number` type
  - adds functions test to cover the case 


### Checklist

Delete any items that are not applicable to this PR.


- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
vitaliidm authored Dec 14, 2023
1 parent 5cab10b commit 424708c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import objectHash from 'object-hash';
import sortBy from 'lodash/sortBy';

import type { SuppressionFieldsLatest } from '@kbn/rule-registry-plugin/common/schemas';
import {
Expand Down Expand Up @@ -79,9 +80,7 @@ export const wrapSuppressedThresholdALerts = ({
completeRule.ruleParams.ruleId
);

const suppressedValues = Object.entries(bucket.key)
.map(([key, value]) => value)
.sort((a, b) => a.localeCompare(b));
const suppressedValues = sortBy(Object.entries(bucket.key).map(([_, value]) => value));

const id = objectHash([
hit._index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
"properties": {
"name": {
"type": "keyword"
},
"uptime": {
"type": "long"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,82 @@ export default ({ getService }: FtrProviderContext) => {
});
});

// should work correctly if one of the suppressed fields is keyword, another - number
it('should update an existing alert in the time window with multiple fields of different types', async () => {
const id = uuidv4();
const timestamp = '2020-10-28T05:45:00.000Z';
const firstRunDoc = {
id,
'@timestamp': timestamp,
agent: {
name: 'agent-1',
},
host: {
uptime: 100,
},
};

const secondRunDoc = {
...firstRunDoc,
'@timestamp': '2020-10-28T06:15:00.000Z',
};

await indexListOfDocuments([firstRunDoc, firstRunDoc, secondRunDoc, secondRunDoc]);

const rule: ThresholdRuleCreateProps = {
...getThresholdRuleForAlertTesting(['ecs_compliant']),
query: `id:${id}`,
threshold: {
field: ['agent.name', 'host.uptime'],
value: 2,
},
alert_suppression: {
duration: {
value: 2,
unit: 'h',
},
},
from: 'now-35m',
interval: '30m',
};

const { previewId } = await previewRule({
supertest,
rule,
timeframeEnd: new Date('2020-10-28T06:30:00.000Z'),
invocationCount: 2,
});

const previewAlerts = await getPreviewAlerts({
es,
previewId,
sort: ['agent.type', ALERT_ORIGINAL_TIME],
});

expect(previewAlerts.length).toEqual(1);

expect(previewAlerts[0]._source).toEqual(
expect.objectContaining({
[ALERT_SUPPRESSION_TERMS]: [
{
field: 'agent.name',
value: 'agent-1',
},
{
field: 'host.uptime',
value: 100,
},
],
[TIMESTAMP]: '2020-10-28T06:00:00.000Z',
[ALERT_LAST_DETECTED]: '2020-10-28T06:30:00.000Z',
[ALERT_ORIGINAL_TIME]: timestamp,
[ALERT_SUPPRESSION_START]: '2020-10-28T06:00:00.000Z',
[ALERT_SUPPRESSION_END]: '2020-10-28T06:30:00.000Z',
[ALERT_SUPPRESSION_DOCS_COUNT]: 1,
})
);
});

it('should correctly suppress when using a timestamp override', async () => {
const id = uuidv4();
const timestamp = '2020-10-28T05:45:00.000Z';
Expand Down

0 comments on commit 424708c

Please sign in to comment.