Skip to content

Commit 13ec60d

Browse files
committed
Add endpoint exception creation API validation
1 parent b48162b commit 13ec60d

File tree

7 files changed

+2692
-0
lines changed

7 files changed

+2692
-0
lines changed

x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '../../common/schemas';
1717

1818
import { getExceptionListClient } from './utils/get_exception_list_client';
19+
import { endpointDisallowedFields } from './endpoint_disallowed_fields';
1920

2021
export const createExceptionListItemRoute = (router: IRouter): void => {
2122
router.post(
@@ -70,6 +71,22 @@ export const createExceptionListItemRoute = (router: IRouter): void => {
7071
statusCode: 409,
7172
});
7273
} else {
74+
if (exceptionList.type === 'endpoint') {
75+
for (const entry of entries) {
76+
if (entry.type === 'list') {
77+
return siemResponse.error({
78+
body: `cannot add exception item with entry of type "list" to endpoint exception list`,
79+
statusCode: 400,
80+
});
81+
}
82+
if (endpointDisallowedFields.includes(entry.field)) {
83+
return siemResponse.error({
84+
body: `cannot add endpoint exception item on field ${entry.field}`,
85+
statusCode: 400,
86+
});
87+
}
88+
}
89+
}
7390
const createdList = await exceptionLists.createExceptionListItem({
7491
_tags,
7592
comments,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
export const endpointDisallowedFields = [
8+
'file.Ext.quarantine_path',
9+
'file.Ext.quarantine_result',
10+
'process.entity_id',
11+
'process.parent.entity_id',
12+
'process.ancestry',
13+
];

x-pack/test/api_integration/apis/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ export default function ({ loadTestFile }) {
3131
loadTestFile(require.resolve('./transform'));
3232
loadTestFile(require.resolve('./endpoint'));
3333
loadTestFile(require.resolve('./ingest_manager'));
34+
loadTestFile(require.resolve('./lists'));
3435
});
3536
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import expect from '@kbn/expect/expect.js';
8+
import { FtrProviderContext } from '../../ftr_provider_context';
9+
10+
export default function ({ getService }: FtrProviderContext) {
11+
const esArchiver = getService('esArchiver');
12+
const supertest = getService('supertest');
13+
describe('Lists API', () => {
14+
before(async () => await esArchiver.load('lists'));
15+
16+
after(async () => await esArchiver.unload('lists'));
17+
18+
it('should return a 400 if an endpoint exception item with a list-based entry is provided', async () => {
19+
const badItem = {
20+
namespace_type: 'agnostic',
21+
description: 'bad endpoint item for testing',
22+
name: 'bad endpoint item',
23+
list_id: 'endpoint_list',
24+
type: 'simple',
25+
entries: [
26+
{
27+
type: 'list',
28+
field: 'some.field',
29+
operator: 'included',
30+
list: {
31+
id: 'somelist',
32+
type: 'keyword',
33+
},
34+
},
35+
],
36+
};
37+
const { body } = await supertest
38+
.post(`/api/exception_lists/items`)
39+
.set('kbn-xsrf', 'xxx')
40+
.send(badItem)
41+
.expect(400);
42+
expect(body.message).to.eql(
43+
'cannot add exception item with entry of type "list" to endpoint exception list'
44+
);
45+
});
46+
47+
it('should return a 400 if endpoint exception entry has disallowed field', async () => {
48+
const fieldName = 'file.Ext.quarantine_path';
49+
const badItem = {
50+
namespace_type: 'agnostic',
51+
description: 'bad endpoint item for testing',
52+
name: 'bad endpoint item',
53+
list_id: 'endpoint_list',
54+
type: 'simple',
55+
entries: [
56+
{
57+
type: 'match',
58+
field: fieldName,
59+
operator: 'included',
60+
value: 'doesnt matter',
61+
},
62+
],
63+
};
64+
const { body } = await supertest
65+
.post(`/api/exception_lists/items`)
66+
.set('kbn-xsrf', 'xxx')
67+
.send(badItem)
68+
.expect(400);
69+
expect(body.message).to.eql(`cannot add endpoint exception item on field ${fieldName}`);
70+
});
71+
});
72+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import { FtrProviderContext } from '../../ftr_provider_context';
7+
8+
export default function listsAPIIntegrationTests({ loadTestFile }: FtrProviderContext) {
9+
describe('Lists plugin', function () {
10+
this.tags(['lists']);
11+
loadTestFile(require.resolve('./create_exception_list_item'));
12+
});
13+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"type": "doc",
3+
"value": {
4+
"id": "exception-list-agnostic:1",
5+
"index": ".kibana",
6+
"source": {
7+
"type": "exception-list-agnostic",
8+
"exception-list-agnostic": {
9+
"_tags": [
10+
"endpoint",
11+
"process",
12+
"malware",
13+
"os:linux"
14+
],
15+
"created_at": "2020-04-23T00:19:13.289Z",
16+
"created_by": "user_name",
17+
"description": "This is a sample endpoint type exception list",
18+
"list_id": "endpoint_list",
19+
"list_type": "list",
20+
"name": "Sample Endpoint Exception List",
21+
"tags": [
22+
"user added string for a tag",
23+
"malware"
24+
],
25+
"tie_breaker_id": "77fd1909-6786-428a-a671-30229a719c1f",
26+
"type": "endpoint",
27+
"updated_by": "user_name"
28+
}
29+
}
30+
}
31+
}
32+
33+
{
34+
"type": "doc",
35+
"value": {
36+
"id": "exception-list-agnostic:2",
37+
"index": ".kibana",
38+
"source": {
39+
"type": "exception-list-agnostic",
40+
"exception-list-agnostic": {
41+
"_tags": [
42+
"endpoint",
43+
"process",
44+
"malware",
45+
"os:linux"
46+
],
47+
"comments": [],
48+
"created_at": "2020-04-23T00:19:13.289Z",
49+
"created_by": "user_name",
50+
"description": "This is a sample endpoint type exception",
51+
"entries": [
52+
{
53+
"entries": [
54+
{
55+
"field": "nested.field",
56+
"operator": "included",
57+
"type": "match",
58+
"value": "some value"
59+
}
60+
],
61+
"field": "some.parentField",
62+
"type": "nested"
63+
},
64+
{
65+
"field": "some.not.nested.field",
66+
"operator": "included",
67+
"type": "match",
68+
"value": "some value"
69+
}
70+
],
71+
"item_id": "endpoint_list_item",
72+
"list_id": "endpoint_list",
73+
"list_type": "item",
74+
"name": "Sample Endpoint Exception List",
75+
"tags": [
76+
"user added string for a tag",
77+
"malware"
78+
],
79+
"tie_breaker_id": "77fd1909-6786-428a-a671-30229a719c1f",
80+
"type": "simple",
81+
"updated_by": "user_name"
82+
}
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)