From fb72b18b5031781cbfe0aac158928233c3748fca Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Mon, 9 May 2022 11:56:14 +0200 Subject: [PATCH 1/9] Add Osquery to alert_context_menu --- .../common/ecs/agent/index.ts | 1 + .../timeline_actions/alert_context_menu.tsx | 30 +++++++++++++++++-- .../timeline/factory/helpers/constants.ts | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/common/ecs/agent/index.ts b/x-pack/plugins/security_solution/common/ecs/agent/index.ts index 2332b60f1a3ca..7084214a9b876 100644 --- a/x-pack/plugins/security_solution/common/ecs/agent/index.ts +++ b/x-pack/plugins/security_solution/common/ecs/agent/index.ts @@ -7,4 +7,5 @@ export interface AgentEcs { type?: string[]; + id?: string[]; } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index a6af9febe8b3e..2838a63baae7b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -13,6 +13,8 @@ import { connect, ConnectedProps } from 'react-redux'; import { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { get } from 'lodash/fp'; import { DEFAULT_ACTION_BUTTON_WIDTH } from '@kbn/timelines-plugin/public'; +import { OsqueryActionItem } from '../../osquery/osquery_action_item'; +import { OsqueryFlyout } from '../../osquery/osquery_flyout'; import { useRouteSpy } from '../../../../common/utils/route/use_route_spy'; import { buildGetAlertByIdQuery } from '../../../../common/components/exceptions/helpers'; import { useUserPrivileges } from '../../../../common/components/user_privileges'; @@ -63,6 +65,7 @@ const AlertContextMenuComponent: React.FC { const [isPopoverOpen, setPopover] = useState(false); + const [isOsqueryFlyoutOpen, setOsqueryFlyoutOpen] = useState(false); const [routeProps] = useRouteSpy(); const onMenuItemClick = useCallback(() => { @@ -175,16 +178,36 @@ const AlertContextMenuComponent: React.FC get(0, ecsRowData?.agent?.id), [ecsRowData]); + const handleOnOsqueryClick = useCallback(() => { + setOsqueryFlyoutOpen((prevValue) => !prevValue); + setPopover(false); + }, []); + + const osqueryActionItem = useMemo( + () => + OsqueryActionItem({ + handleClick: handleOnOsqueryClick, + }), + [handleOnOsqueryClick] + ); + const items: React.ReactElement[] = useMemo( () => !isEvent && ruleId - ? [...addToCaseActionItems, ...statusActionItems, ...exceptionActionItems] - : [...addToCaseActionItems, ...eventFilterActionItems], + ? [ + ...addToCaseActionItems, + ...statusActionItems, + ...exceptionActionItems, + osqueryActionItem, + ] + : [...addToCaseActionItems, ...eventFilterActionItems, osqueryActionItem], [ statusActionItems, addToCaseActionItems, eventFilterActionItems, exceptionActionItems, + osqueryActionItem, isEvent, ruleId, ] @@ -228,6 +251,9 @@ const AlertContextMenuComponent: React.FC )} + {isOsqueryFlyoutOpen && agentId && ecsRowData != null && ( + + )} ); }; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/constants.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/constants.ts index 211edec96b8ac..068b52b8cd821 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/constants.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/constants.ts @@ -94,6 +94,7 @@ export const TIMELINE_EVENTS_FIELDS = [ 'event.timezone', 'event.type', 'agent.type', + 'agent.id', 'auditd.result', 'auditd.session', 'auditd.data.acct', From afc1bd7ddacd42bc170823ddcbe6dbd8d95993e6 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Mon, 9 May 2022 12:16:49 +0200 Subject: [PATCH 2/9] add test --- .../osquery/cypress/integration/all/alerts.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts index 21d3584b9fc46..b8ec805b92a5f 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts @@ -34,10 +34,9 @@ describe('Alert Event Details', () => { runKbnArchiverScript(ArchiverMethod.UNLOAD, 'rule'); }); - it('should be able to run live query', () => { + it('should prepare packs and alert rules', () => { const PACK_NAME = 'testpack'; const RULE_NAME = 'Test-rule'; - const TIMELINE_NAME = 'Untitled timeline'; navigateTo('/app/osquery/packs'); preparePack(PACK_NAME); findAndClickButton('Edit'); @@ -57,8 +56,14 @@ describe('Alert Event Details', () => { cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'false'); cy.getBySel('ruleSwitch').click(); cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true'); + }); + + it('should be able to run live query and add to timeline (-depending on the previous test)', () => { + const TIMELINE_NAME = 'Untitled timeline'; cy.visit('/app/security/alerts'); cy.wait(500); + cy.getBySel('timeline-context-menu-button').should('exist').first().click(); + cy.getBySel('osquery-action-item').should('exist').contains('Run Osquery'); cy.getBySel('expand-event').first().click(); cy.getBySel('take-action-dropdown-btn').click(); cy.getBySel('osquery-action-item').click(); From d433153176019a8051516648d372dcc0aede0e62 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Mon, 9 May 2022 14:15:31 +0200 Subject: [PATCH 3/9] update snaoshots --- .../search_strategy/timeline/eql/helpers.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts index 1b58e63ec8752..0cb151a316f28 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts @@ -205,6 +205,9 @@ describe('Search Strategy EQL helper', () => { "_id": "qhymg3cBX5UUcOOYP3Ec", "_index": ".ds-logs-endpoint.events.security-default-2021.02.05-000005", "agent": Object { + "id": Array [ + "1d15cf9e-3dc7-5b97-f586-743f7c2518b2", + ], "type": Array [ "endpoint", ], @@ -332,6 +335,9 @@ describe('Search Strategy EQL helper', () => { "_id": "qxymg3cBX5UUcOOYP3Ec", "_index": ".ds-logs-endpoint.events.security-default-2021.02.05-000005", "agent": Object { + "id": Array [ + "1d15cf9e-3dc7-5b97-f586-743f7c2518b2", + ], "type": Array [ "endpoint", ], @@ -472,6 +478,9 @@ describe('Search Strategy EQL helper', () => { "_id": "rBymg3cBX5UUcOOYP3Ec", "_index": ".ds-logs-endpoint.events.security-default-2021.02.05-000005", "agent": Object { + "id": Array [ + "1d15cf9e-3dc7-5b97-f586-743f7c2518b2", + ], "type": Array [ "endpoint", ], @@ -588,6 +597,9 @@ describe('Search Strategy EQL helper', () => { "_id": "pxymg3cBX5UUcOOYP3Ec", "_index": ".ds-logs-endpoint.events.process-default-2021.02.02-000005", "agent": Object { + "id": Array [ + "1d15cf9e-3dc7-5b97-f586-743f7c2518b2", + ], "type": Array [ "endpoint", ], From 6e55aef74ce946269a56693ea820dee441e1435d Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Wed, 11 May 2022 09:24:46 +0200 Subject: [PATCH 4/9] add isOsqueryAvailable check --- .../timeline_actions/alert_context_menu.tsx | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 18ed53110f2f2..59dd897ae4710 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -13,6 +13,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { get } from 'lodash/fp'; import { DEFAULT_ACTION_BUTTON_WIDTH } from '@kbn/timelines-plugin/public'; +import { useKibana } from '../../../../common/lib/kibana'; import { OsqueryActionItem } from '../../osquery/osquery_action_item'; import { OsqueryFlyout } from '../../osquery/osquery_flyout'; import { useRouteSpy } from '../../../../common/utils/route/use_route_spy'; @@ -67,6 +68,7 @@ const AlertContextMenuComponent: React.FC { setPopover(false); @@ -189,6 +191,9 @@ const AlertContextMenuComponent: React.FC get(0, ecsRowData?.agent?.id), [ecsRowData]); + const osqueryAvailable = osquery?.isOsqueryAvailable({ + agentId: agentId || '', + }); const handleOnOsqueryClick = useCallback(() => { setOsqueryFlyoutOpen((prevValue) => !prevValue); setPopover(false); @@ -209,17 +214,22 @@ const AlertContextMenuComponent: React.FC Date: Thu, 19 May 2022 09:19:46 +0200 Subject: [PATCH 5/9] change hitting api for osqueryAvailalbe into checking agentId --- .../timeline_actions/alert_context_menu.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 4f848ee7998e1..d34e42a274fd2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -13,7 +13,6 @@ import { connect, ConnectedProps } from 'react-redux'; import { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { get } from 'lodash/fp'; import { DEFAULT_ACTION_BUTTON_WIDTH } from '@kbn/timelines-plugin/public'; -import { useKibana } from '../../../../common/lib/kibana'; import { OsqueryActionItem } from '../../osquery/osquery_action_item'; import { OsqueryFlyout } from '../../osquery/osquery_flyout'; import { useRouteSpy } from '../../../../common/utils/route/use_route_spy'; @@ -68,7 +67,6 @@ const AlertContextMenuComponent: React.FC { setPopover(false); @@ -192,9 +190,7 @@ const AlertContextMenuComponent: React.FC get(0, ecsRowData?.agent?.id), [ecsRowData]); - const osqueryAvailable = osquery?.isOsqueryAvailable({ - agentId: agentId || '', - }); + const handleOnOsqueryClick = useCallback(() => { setOsqueryFlyoutOpen((prevValue) => !prevValue); setPopover(false); @@ -215,12 +211,12 @@ const AlertContextMenuComponent: React.FC Date: Thu, 19 May 2022 11:38:43 +0200 Subject: [PATCH 6/9] refactor actionItem to be coming from hook --- .../timeline_actions/alert_context_menu.tsx | 16 ++++------- .../osquery/osquery_action_item.tsx | 20 +++++++------- .../use_osquery_context_action_item.tsx | 27 +++++++++++++++++++ 3 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index d34e42a274fd2..52ae73950534c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -13,7 +13,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { get } from 'lodash/fp'; import { DEFAULT_ACTION_BUTTON_WIDTH } from '@kbn/timelines-plugin/public'; -import { OsqueryActionItem } from '../../osquery/osquery_action_item'; +import { useOsqueryContextActionItem } from '../../osquery/use_osquery_context_action_item'; import { OsqueryFlyout } from '../../osquery/osquery_flyout'; import { useRouteSpy } from '../../../../common/utils/route/use_route_spy'; import { buildGetAlertByIdQuery } from '../../../../common/components/exceptions/helpers'; @@ -196,13 +196,7 @@ const AlertContextMenuComponent: React.FC - OsqueryActionItem({ - handleClick: handleOnOsqueryClick, - }), - [handleOnOsqueryClick] - ); + const { osqueryActionItems } = useOsqueryContextActionItem({ handleClick: handleOnOsqueryClick }); const items: React.ReactElement[] = useMemo( () => @@ -211,12 +205,12 @@ const AlertContextMenuComponent: React.FC void; } -export const OsqueryActionItem = ({ handleClick }: IProps) => { - return ( - - {ACTION_OSQUERY} - - ); -}; +export const OsqueryActionItem = ({ handleClick }: IProps) => ( + + {ACTION_OSQUERY} + +); diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx new file mode 100644 index 0000000000000..6dd7d823dbc00 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { OsqueryActionItem } from './osquery_action_item'; +import { useKibana } from '../../../common/lib/kibana'; + +interface IProps { + handleClick: () => void; +} + +export const useOsqueryContextActionItem = ({ handleClick }: IProps): any => { + const osqueryActionItem = useMemo( + () => , + [handleClick] + ); + const permissions = useKibana().services.application.capabilities.osquery; + + return { + osqueryActionItems: + permissions.writeLiveQueries || permissions.runSavedQueries ? [osqueryActionItem] : [], + }; +}; From bd98ae57a654548a29d8a0c6ed709cefecbe8168 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Thu, 19 May 2022 11:52:11 +0200 Subject: [PATCH 7/9] remove any --- .../components/osquery/use_osquery_context_action_item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx index 6dd7d823dbc00..515beb638c588 100644 --- a/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx @@ -13,7 +13,7 @@ interface IProps { handleClick: () => void; } -export const useOsqueryContextActionItem = ({ handleClick }: IProps): any => { +export const useOsqueryContextActionItem = ({ handleClick }: IProps) => { const osqueryActionItem = useMemo( () => , [handleClick] From 281e94d11f7b2b78e1b5bed1a1c1c1d08af6b00b Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Thu, 19 May 2022 13:19:01 +0200 Subject: [PATCH 8/9] add optional chaining, due to test --- .../components/osquery/use_osquery_context_action_item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx index 515beb638c588..41a78eb32619f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/osquery/use_osquery_context_action_item.tsx @@ -22,6 +22,6 @@ export const useOsqueryContextActionItem = ({ handleClick }: IProps) => { return { osqueryActionItems: - permissions.writeLiveQueries || permissions.runSavedQueries ? [osqueryActionItem] : [], + permissions?.writeLiveQueries || permissions?.runSavedQueries ? [osqueryActionItem] : [], }; }; From 42d08817dec37b7df55cc3325b5f9b0087bc24cf Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Thu, 19 May 2022 16:48:38 +0200 Subject: [PATCH 9/9] fix tests --- x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts index b8ec805b92a5f..4ef3e263df01c 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts @@ -61,8 +61,8 @@ describe('Alert Event Details', () => { it('should be able to run live query and add to timeline (-depending on the previous test)', () => { const TIMELINE_NAME = 'Untitled timeline'; cy.visit('/app/security/alerts'); - cy.wait(500); - cy.getBySel('timeline-context-menu-button').should('exist').first().click(); + cy.getBySel('header-page-title').contains('Alerts').should('exist'); + cy.getBySel('timeline-context-menu-button').first().click({ force: true }); cy.getBySel('osquery-action-item').should('exist').contains('Run Osquery'); cy.getBySel('expand-event').first().click(); cy.getBySel('take-action-dropdown-btn').click();