Skip to content

Commit

Permalink
[Security Solution][Detection Engine] adds EQL common fields ftr test…
Browse files Browse the repository at this point in the history
… for shell alert (#178150)

## Summary

- adds explicit FTR tests to ensure common fields in shell alert
generated by sequences EQL rule are preserved
  • Loading branch information
vitaliidm authored Mar 14, 2024
1 parent 52ff9b0 commit f0239e1
Showing 1 changed file with 89 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { v4 as uuidv4 } from 'uuid';
import expect from '@kbn/expect';
import {
ALERT_REASON,
Expand Down Expand Up @@ -35,6 +36,7 @@ import {
getOpenAlerts,
getPreviewAlerts,
previewRule,
dataGeneratorFactory,
} from '../../../../utils';
import {
createRule,
Expand Down Expand Up @@ -65,18 +67,26 @@ export default ({ getService }: FtrProviderContext) => {
const auditPath = dataPathBuilder.getPath('auditbeat/hosts');

describe('@ess @serverless EQL type rules', () => {
const { indexListOfDocuments } = dataGeneratorFactory({
es,
index: 'ecs_compliant',
log,
});

before(async () => {
await esArchiver.load(auditPath);
await esArchiver.load(
'x-pack/test/functional/es_archives/security_solution/timestamp_override_6'
);
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
});

after(async () => {
await esArchiver.unload(auditPath);
await esArchiver.unload(
'x-pack/test/functional/es_archives/security_solution/timestamp_override_6'
);
await esArchiver.unload('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
await deleteAllAlerts(supertest, log, es);
await deleteAllRules(supertest, log);
});
Expand Down Expand Up @@ -532,6 +542,85 @@ export default ({ getService }: FtrProviderContext) => {
});
});

it('ensures common fields are present in generated shell alert', async () => {
const id = uuidv4();
const doc1 = {
id,
agent: {
name: 'agent-1',
type: 'auditbeat',
version: '8.13.0',
},
client: {
ip: ['127.0.0.1', '127.0.0.2'],
},
'host.name': 'host-0',
};

const doc2 = {
id,
agent: {
name: 'agent-0',
type: 'auditbeat',
version: '8.13.0',
},
client: {
ip: ['127.0.0.1', '127.0.0.3'],
},
'host.name': 'host-0',
};

await indexListOfDocuments([
{ '@timestamp': '2020-10-28T06:15:00.000Z', ...doc1 },
{ '@timestamp': '2020-10-28T06:16:00.000Z', ...doc2 },
]);

const rule: EqlRuleCreateProps = {
...getEqlRuleForAlertTesting(['ecs_compliant']),
query: `sequence [any where id == "${id}" ] [any where true]`,
from: 'now-35m',
interval: '30m',
};
const { previewId } = await previewRule({
supertest,
rule,
timeframeEnd: new Date('2020-10-28T06:30:00.000Z'),
});

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

expect(previewAlerts).to.have.length(3);

const buildingBlockAlerts = previewAlerts.filter(
(alert) => alert._source?.['kibana.alert.building_block_type']
);
const shellAlert = previewAlerts.filter(
(alert) => !alert._source?.['kibana.alert.building_block_type']
)[0];

// check building block alert retains all fields from source documents
// alerts sorted by agent.name, so we assert it against agent-0 document
expect(buildingBlockAlerts[0]._source).eql({
...buildingBlockAlerts[0]._source,
...doc2,
});

expect(buildingBlockAlerts[1]._source).eql({
...buildingBlockAlerts[1]._source,
...doc1,
});

// shell alert should have only common properties from building block alerts
expect(shellAlert._source?.agent).eql({
type: 'auditbeat',
version: '8.13.0',
// agent name is absent as this field is not common
});
// only common values in array are present
expect(shellAlert._source?.client).eql({ ip: ['127.0.0.1'] });
expect(shellAlert._source?.['host.name']).be('host-0');
});

it('generates up to max_alerts with an EQL rule', async () => {
const maxAlerts = 200;
const rule: EqlRuleCreateProps = {
Expand Down

0 comments on commit f0239e1

Please sign in to comment.