[Security] Add telemetry for new protection types and arrays of objects (#97624)

* Add telemetry for new protection types and arrays of objects
* Add malware_signature to process.Ext + dll.Ext
* Fix comments for base fields
* Move naming convention disable to a line
* Fix unit test for rule.version
This commit is contained in:
Ross Wolf 2021-04-20 14:25:21 -04:00 committed by GitHub
parent 43850fae72
commit 8b20cbc3d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 48 deletions

View file

@ -38,6 +38,7 @@ describe('TelemetryEventsSender', () => {
id: 'X',
name: 'Y',
ruleset: 'Z',
version: '100',
},
file: {
size: 3,
@ -97,6 +98,7 @@ describe('TelemetryEventsSender', () => {
id: 'X',
name: 'Y',
ruleset: 'Z',
version: '100',
},
file: {
size: 3,
@ -253,6 +255,57 @@ describe('allowlistEventFields', () => {
});
});
it('filters arrays of objects', () => {
const event = {
a: [
{
a1: 'a1',
},
],
b: {
b1: 'b1',
},
c: [
{
d: 'd1',
e: 'e1',
f: 'f1',
},
{
d: 'd2',
e: 'e2',
f: 'f2',
},
{
d: 'd3',
e: 'e3',
f: 'f3',
},
],
};
expect(copyAllowlistedFields(allowlist, event)).toStrictEqual({
a: [
{
a1: 'a1',
},
],
b: {
b1: 'b1',
},
c: [
{
d: 'd1',
},
{
d: 'd2',
},
{
d: 'd3',
},
],
});
});
it("doesn't create empty objects", () => {
const event = {
a: 'a',

View file

@ -21,16 +21,8 @@ import {
} from '../../../../task_manager/server';
import { TelemetryDiagTask } from './task';
export type SearchTypes =
| string
| string[]
| number
| number[]
| boolean
| boolean[]
| object
| object[]
| undefined;
type BaseSearchTypes = string | number | boolean | object;
export type SearchTypes = BaseSearchTypes | BaseSearchTypes[] | undefined;
export interface TelemetryEvent {
[key: string]: SearchTypes;
@ -294,8 +286,8 @@ interface AllowlistFields {
}
// Allow list process fields within events. This includes "process" and "Target.process".'
/* eslint-disable @typescript-eslint/naming-convention */
const allowlistProcessFields: AllowlistFields = {
args: true,
name: true,
executable: true,
command_line: true,
@ -306,48 +298,23 @@ const allowlistProcessFields: AllowlistFields = {
architecture: true,
code_signature: true,
dll: true,
malware_signature: true,
token: {
integrity_level_name: true,
},
},
parent: {
name: true,
executable: true,
command_line: true,
hash: true,
Ext: {
architecture: true,
code_signature: true,
dll: true,
token: {
integrity_level_name: true,
},
},
uptime: true,
pid: true,
ppid: true,
},
thread: true,
};
// Allow list for the data we include in the events. True means that it is deep-cloned
// blindly. Object contents means that we only copy the fields that appear explicitly in
// the sub-object.
const allowlistEventFields: AllowlistFields = {
'@timestamp': true,
agent: true,
Endpoint: true,
Memory_protection: true,
Ransomware: true,
data_stream: true,
ecs: true,
elastic: true,
event: true,
rule: {
id: true,
// Allow list for event-related fields, which can also be nested under events[]
const allowlistBaseEventFields: AllowlistFields = {
dll: {
name: true,
ruleset: true,
path: true,
code_signature: true,
malware_signature: true,
},
event: true,
file: {
name: true,
path: true,
@ -365,13 +332,52 @@ const allowlistEventFields: AllowlistFields = {
quarantine_message: true,
},
},
process: {
parent: allowlistProcessFields,
...allowlistProcessFields,
},
network: {
direction: true,
},
registry: {
hive: true,
key: true,
path: true,
value: true,
},
Target: {
process: {
parent: allowlistProcessFields,
...allowlistProcessFields,
},
},
};
// Allow list for the data we include in the events. True means that it is deep-cloned
// blindly. Object contents means that we only copy the fields that appear explicitly in
// the sub-object.
const allowlistEventFields: AllowlistFields = {
'@timestamp': true,
agent: true,
Endpoint: true,
/* eslint-disable @typescript-eslint/naming-convention */
Memory_protection: true,
Ransomware: true,
data_stream: true,
ecs: true,
elastic: true,
// behavioral protection re-nests some field sets under events.*
events: allowlistBaseEventFields,
rule: {
id: true,
name: true,
ruleset: true,
version: true,
},
host: {
os: true,
},
process: allowlistProcessFields,
Target: {
process: allowlistProcessFields,
},
...allowlistBaseEventFields,
};
export function copyAllowlistedFields(
@ -383,6 +389,12 @@ export function copyAllowlistedFields(
if (eventValue !== null && eventValue !== undefined) {
if (allowValue === true) {
return { ...newEvent, [allowKey]: eventValue };
} else if (typeof allowValue === 'object' && Array.isArray(eventValue)) {
const subValues = eventValue.filter((v) => typeof v === 'object');
return {
...newEvent,
[allowKey]: subValues.map((v) => copyAllowlistedFields(allowValue, v as TelemetryEvent)),
};
} else if (typeof allowValue === 'object' && typeof eventValue === 'object') {
const values = copyAllowlistedFields(allowValue, eventValue as TelemetryEvent);
return {