[SIEM] [Detections] Reject on value list + other exception entries in single exception item (#73158)

Add validation to reject when value list and other exception type are entries in the same exception item. Also adds tests for this situation on the schema validation
This commit is contained in:
Devin W. Hurley 2020-07-28 12:46:20 -04:00 committed by GitHub
parent 1dbea34d2d
commit 12e7d995f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 10 deletions

View file

@ -11,10 +11,22 @@ import { getEntryListMock } from './entry_list.mock';
import { getEntryExistsMock } from './entry_exists.mock';
import { getEntryNestedMock } from './entry_nested.mock';
export const getEntriesArrayMock = (): EntriesArray => [
export const getListAndNonListEntriesArrayMock = (): EntriesArray => [
{ ...getEntryMatchMock() },
{ ...getEntryMatchAnyMock() },
{ ...getEntryListMock() },
{ ...getEntryExistsMock() },
{ ...getEntryNestedMock() },
];
export const getListEntriesArrayMock = (): EntriesArray => [
{ ...getEntryListMock() },
{ ...getEntryListMock() },
];
export const getEntriesArrayMock = (): EntriesArray => [
{ ...getEntryMatchMock() },
{ ...getEntryMatchAnyMock() },
{ ...getEntryExistsMock() },
{ ...getEntryNestedMock() },
];

View file

@ -11,10 +11,13 @@ import { foldLeftRight, getPaths } from '../../siem_common_deps';
import { getEntryMatchMock } from './entry_match.mock';
import { getEntryMatchAnyMock } from './entry_match_any.mock';
import { getEntryListMock } from './entry_list.mock';
import { getEntryExistsMock } from './entry_exists.mock';
import { getEntryNestedMock } from './entry_nested.mock';
import { getEntriesArrayMock } from './entries.mock';
import {
getEntriesArrayMock,
getListAndNonListEntriesArrayMock,
getListEntriesArrayMock,
} from './entries.mock';
import { nonEmptyEntriesArray } from './non_empty_entries_array';
import { EntriesArray } from './entries';
@ -80,7 +83,7 @@ describe('non_empty_entries_array', () => {
});
test('it should validate an array of "list" entries', () => {
const payload: EntriesArray = [{ ...getEntryListMock() }, { ...getEntryListMock() }];
const payload: EntriesArray = [...getListEntriesArrayMock()];
const decoded = nonEmptyEntriesArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
@ -106,6 +109,15 @@ describe('non_empty_entries_array', () => {
expect(message.schema).toEqual(payload);
});
test('it should NOT validate an array of entries of value list and non-value list entries', () => {
const payload: EntriesArray = [...getListAndNonListEntriesArrayMock()];
const decoded = nonEmptyEntriesArray.decode(payload);
const message = pipe(decoded, foldLeftRight);
expect(getPaths(left(message.errors))).toEqual(['Cannot have entry of type list and other']);
expect(message.schema).toEqual({});
});
test('it should NOT validate an array of non entries', () => {
const payload = [1];
const decoded = nonEmptyEntriesArray.decode(payload);

View file

@ -8,6 +8,7 @@ import * as t from 'io-ts';
import { Either } from 'fp-ts/lib/Either';
import { EntriesArray, entriesArray } from './entries';
import { entriesList } from './entry_list';
/**
* Types the nonEmptyEntriesArray as:
@ -21,6 +22,14 @@ export const nonEmptyEntriesArray = new t.Type<EntriesArray, EntriesArray, unkno
if (Array.isArray(input) && input.length === 0) {
return t.failure(input, context);
} else {
if (
Array.isArray(input) &&
input.some((entry) => entriesList.is(entry)) &&
input.some((entry) => !entriesList.is(entry))
) {
// fail when an exception item contains both a value list entry and a non-value list entry
return t.failure(input, context, 'Cannot have entry of type list and other');
}
return entriesArray.validate(input, context);
}
},

View file

@ -93,12 +93,6 @@ describe('Exception viewer helpers', () => {
operator: 'is one of',
value: ['some host name'],
},
{
fieldName: 'host.name',
isNested: false,
operator: 'is in list',
value: 'some-list-id',
},
{
fieldName: 'host.name',
isNested: false,