[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:
parent
43850fae72
commit
8b20cbc3d8
|
@ -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',
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue