From 280f7f47f19f0f4452f8fb47d8d0805b8fd46dcf Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Thu, 5 Nov 2020 17:39:54 +0000 Subject: [PATCH] Filter out read access to config and telemetry obj (#82314) * Filter out read access to config and telemetry obj * Fix eslint errors --- .../server/audit/audit_events.test.ts | 57 +++++++++++++++++++ .../security/server/audit/audit_events.ts | 10 +++- .../server/audit/audit_service.test.ts | 20 +++++++ .../security/server/audit/audit_service.ts | 7 ++- 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security/server/audit/audit_events.test.ts b/x-pack/plugins/security/server/audit/audit_events.test.ts index 1713badede2f7..c826bb1d33f99 100644 --- a/x-pack/plugins/security/server/audit/audit_events.test.ts +++ b/x-pack/plugins/security/server/audit/audit_events.test.ts @@ -106,6 +106,63 @@ describe('#savedObjectEvent', () => { `); }); + test('does create event for read access of saved objects', () => { + expect( + savedObjectEvent({ + action: SavedObjectAction.GET, + savedObject: { type: 'dashboard', id: 'SAVED_OBJECT_ID' }, + }) + ).not.toBeUndefined(); + expect( + savedObjectEvent({ + action: SavedObjectAction.FIND, + savedObject: { type: 'dashboard', id: 'SAVED_OBJECT_ID' }, + }) + ).not.toBeUndefined(); + }); + + test('does not create event for read access of config or telemetry objects', () => { + expect( + savedObjectEvent({ + action: SavedObjectAction.GET, + savedObject: { type: 'config', id: 'SAVED_OBJECT_ID' }, + }) + ).toBeUndefined(); + expect( + savedObjectEvent({ + action: SavedObjectAction.GET, + savedObject: { type: 'telemetry', id: 'SAVED_OBJECT_ID' }, + }) + ).toBeUndefined(); + expect( + savedObjectEvent({ + action: SavedObjectAction.FIND, + savedObject: { type: 'config', id: 'SAVED_OBJECT_ID' }, + }) + ).toBeUndefined(); + expect( + savedObjectEvent({ + action: SavedObjectAction.FIND, + savedObject: { type: 'telemetry', id: 'SAVED_OBJECT_ID' }, + }) + ).toBeUndefined(); + }); + + test('does create event for write access of config or telemetry objects', () => { + expect( + savedObjectEvent({ + action: SavedObjectAction.UPDATE, + savedObject: { type: 'config', id: 'SAVED_OBJECT_ID' }, + }) + ).not.toBeUndefined(); + expect( + savedObjectEvent({ + action: SavedObjectAction.UPDATE, + savedObject: { type: 'telemetry', id: 'SAVED_OBJECT_ID' }, + }) + ).not.toBeUndefined(); + }); + test('creates event with `success` outcome for `REMOVE_REFERENCES` action', () => { expect( savedObjectEvent({ diff --git a/x-pack/plugins/security/server/audit/audit_events.ts b/x-pack/plugins/security/server/audit/audit_events.ts index e3c1f95349c92..6aba78c936071 100644 --- a/x-pack/plugins/security/server/audit/audit_events.ts +++ b/x-pack/plugins/security/server/audit/audit_events.ts @@ -220,7 +220,7 @@ export function savedObjectEvent({ deleteFromSpaces, outcome, error, -}: SavedObjectParams): AuditEvent { +}: SavedObjectParams): AuditEvent | undefined { const doc = savedObject ? `${savedObject.type} [id=${savedObject.id}]` : 'saved objects'; const [present, progressive, past] = eventVerbs[action]; const message = error @@ -230,6 +230,14 @@ export function savedObjectEvent({ : `User has ${past} ${doc}`; const type = eventTypes[action]; + if ( + type === EventType.ACCESS && + savedObject && + (savedObject.type === 'config' || savedObject.type === 'telemetry') + ) { + return; + } + return { message, event: { diff --git a/x-pack/plugins/security/server/audit/audit_service.test.ts b/x-pack/plugins/security/server/audit/audit_service.test.ts index e0dd98c7de639..9b30d4dbba456 100644 --- a/x-pack/plugins/security/server/audit/audit_service.test.ts +++ b/x-pack/plugins/security/server/audit/audit_service.test.ts @@ -130,6 +130,26 @@ describe('#asScoped', () => { audit.asScoped(request).log({ message: 'MESSAGE', event: { action: 'ACTION' } }); expect(logger.info).not.toHaveBeenCalled(); }); + + it('does not log to audit logger if no event was generated', async () => { + const audit = new AuditService(logger).setup({ + license, + config: { + enabled: true, + ignore_filters: [{ actions: ['ACTION'] }], + }, + logging, + http, + getCurrentUser, + getSpaceId, + }); + const request = httpServerMock.createKibanaRequest({ + kibanaRequestState: { requestId: 'REQUEST_ID', requestUuid: 'REQUEST_UUID' }, + }); + + audit.asScoped(request).log(undefined); + expect(logger.info).not.toHaveBeenCalled(); + }); }); describe('#createLoggingConfig', () => { diff --git a/x-pack/plugins/security/server/audit/audit_service.ts b/x-pack/plugins/security/server/audit/audit_service.ts index 31c7e28be3b8c..744e4af56c861 100644 --- a/x-pack/plugins/security/server/audit/audit_service.ts +++ b/x-pack/plugins/security/server/audit/audit_service.ts @@ -27,7 +27,7 @@ export interface LegacyAuditLogger { } export interface AuditLogger { - log: (event: AuditEvent) => void; + log: (event: AuditEvent | undefined) => void; } interface AuditLogMeta extends AuditEvent { @@ -127,7 +127,10 @@ export class AuditService { * }); * ``` */ - const log = (event: AuditEvent) => { + const log: AuditLogger['log'] = (event) => { + if (!event) { + return; + } const user = getCurrentUser(request); const spaceId = getSpaceId(request); const meta: AuditLogMeta = {