[Security Solution][Detection Engine] Test cases for alias failure test cases where we don't copy aliases correctly (#101437)

## Summary

Test cases for signals and aliases, including a failure of where we do not copy alias data at the moment even if the target is an ECS compatible field.

For example with this mapping:

```json
{
  "dynamic": "strict",
  "properties": {
    "@timestamp": {
      "type": "date"
    },
    "host": {
      "properties": {
        "name": {
          "type": "alias",
          "path": "host_alias.name"
        }
      }
    },
    "host_alias": {
      "properties": {
        "name": {
          "type": "keyword"
        }
      }
    }
  }
}
```

If we detect this as a signal hit we should be copying over both:
* `host_alias.name` -> `host.name`
* `host_alias.name` -> `host_alias.name`

to the target signal index, but we only copy:
* `host_alias.name` -> `host_alias.name`

### Checklist

- [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
This commit is contained in:
Frank Hassanabad 2021-06-04 20:34:52 -06:00 committed by GitHub
parent c13ae7ea64
commit 827442b4b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 161 additions and 0 deletions

View file

@ -0,0 +1,65 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createRule,
createSignalsIndex,
deleteAllAlerts,
deleteSignalsIndex,
getRuleForSignalTesting,
getSignalsById,
waitForRuleSuccessOrStatus,
waitForSignalsToBePresent,
} from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
interface HostAlias {
name: string;
}
describe('Tests involving aliases of source indexes and the signals index', () => {
beforeEach(async () => {
await createSignalsIndex(supertest);
await esArchiver.load('security_solution/alias');
});
afterEach(async () => {
await deleteSignalsIndex(supertest);
await deleteAllAlerts(supertest);
await esArchiver.unload('security_solution/alias');
});
it('Should keep the original alias value such as "host_alias" from a source index when the value is indexed', async () => {
const rule = getRuleForSignalTesting(['alias']);
const { id } = await createRule(supertest, rule);
await waitForRuleSuccessOrStatus(supertest, id);
await waitForSignalsToBePresent(supertest, 4, [id]);
const signalsOpen = await getSignalsById(supertest, id);
const hits = signalsOpen.hits.hits.map(
(signal) => (signal._source.host_alias as HostAlias).name
);
expect(hits).to.eql(['host name 1', 'host name 2', 'host name 3', 'host name 4']);
});
// TODO: Make aliases work to where we can have ECS fields such as host.name filled out
it.skip('Should copy alias data from a source index into the signals index in the same position when the target is ECS compatible', async () => {
const rule = getRuleForSignalTesting(['alias']);
const { id } = await createRule(supertest, rule);
await waitForRuleSuccessOrStatus(supertest, id);
await waitForSignalsToBePresent(supertest, 4, [id]);
const signalsOpen = await getSignalsById(supertest, id);
const hits = signalsOpen.hits.hits.map((signal) => (signal._source.host as HostAlias).name);
expect(hits).to.eql(['host name 1', 'host name 2', 'host name 3', 'host name 4']);
});
});
};

View file

@ -13,6 +13,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
describe('', function () {
this.tags('ciGroup11');
loadTestFile(require.resolve('./aliases'));
loadTestFile(require.resolve('./add_actions'));
loadTestFile(require.resolve('./update_actions'));
loadTestFile(require.resolve('./add_prepackaged_rules'));

View file

@ -0,0 +1,59 @@
{
"type": "doc",
"value": {
"id": "1",
"index": "alias",
"source": {
"@timestamp": "2020-10-28T05:00:53.000Z",
"host_alias": {
"name": "host name 1"
}
},
"type": "_doc"
}
}
{
"type": "doc",
"value": {
"id": "2",
"index": "alias",
"source": {
"@timestamp": "2020-10-28T05:01:53.000Z",
"host_alias": {
"name": "host name 2"
}
},
"type": "_doc"
}
}
{
"type": "doc",
"value": {
"id": "3",
"index": "alias",
"source": {
"@timestamp": "2020-10-28T05:02:53.000Z",
"host_alias": {
"name": "host name 3"
}
},
"type": "_doc"
}
}
{
"type": "doc",
"value": {
"id": "4",
"index": "alias",
"source": {
"@timestamp": "2020-10-28T05:03:53.000Z",
"host_alias": {
"name": "host name 4"
}
},
"type": "_doc"
}
}

View file

@ -0,0 +1,36 @@
{
"type": "index",
"value": {
"index": "host_alias",
"mappings": {
"dynamic": "strict",
"properties": {
"@timestamp": {
"type": "date"
},
"host": {
"properties": {
"name": {
"type": "alias",
"path": "host_alias.name"
}
}
},
"host_alias": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
},
"settings": {
"index": {
"refresh_interval": "1s",
"number_of_replicas": "1",
"number_of_shards": "1"
}
}
}
}