From 114c98d3b5df4252f500ea762879524540b2c50a Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Mon, 8 May 2023 18:44:14 -0500 Subject: [PATCH] [Security Solution] fix from-to values investigate in timeline pulled from timestamp instead of @timestamp field (#156884) ## Summary In Kibana 8.8 we've done a huge refactor of the alert table (see [PR](https://github.com/elastic/kibana/pull/149128)). The new table's trigger actions are no longer some of the Security Solution server side methods that were adding a `timestamp` field to the response (see [here](https://github.com/elastic/kibana/blob/main/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/format_timeline_data.ts#L28)). That `timestamp` field was basically a duplication of the `@timestamp` field (done via [this helper function](https://github.com/elastic/kibana/blob/main/x-pack/plugins/timelines/server/search_strategy/timeline/factory/helpers/get_timestamp.ts#L12)) Running the stack locally, you would see that clicking on the `Investigate in timeline` icon button or ANY alerts in the alerts table (pretty new or months/years old) would bring the timeline flyout with always the `to` value being the `current date`, and the `from` value being the `current date - kibana.alert.rule.from`. The `timetamp` field [here](https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx#L158) does not exists, so we always fall back to `new Date()` (unless you're looking at an alert generated by a threshold rule, a new terms rule or a suppressed alert). This PR fixes the issue by retrieving the `@timestamp` field instead of the unwanted `timestamp` field. More work will be done in the future to actually entirely remove and cleanup the `timestamp` field (see [this WIP ticket](https://github.com/elastic/kibana/issues/156879)). ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios Before (recorded on May 4th and we're looking at an alert generated on May 3rd) https://user-images.githubusercontent.com/17276605/236509848-a5b0a363-c9c5-4d80-a139-84e3df3a1bd6.mov After https://user-images.githubusercontent.com/17276605/236509884-74805cef-ccf2-4b09-a174-2fcb6b75d4bb.mov Closes https://github.com/elastic/kibana/issues/126077 --- .../public/common/mock/mock_detection_alerts.ts | 2 +- .../components/alerts_table/actions.test.tsx | 7 ++++--- .../detections/components/alerts_table/actions.tsx | 12 ++++++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts b/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts index 7f52db599135ad..3b8a07b7ffeb72 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts +++ b/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts @@ -10,7 +10,7 @@ import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; export const getDetectionAlertMock = (overrides: Partial = {}): Ecs => ({ ...{ _id: '1', - timestamp: '2018-11-05T19:03:25.937Z', + '@timestamp': '2018-11-05T19:03:25.937Z', host: { name: ['apache'], ip: ['192.168.0.1'], diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx index 5ad96cfc322d6a..c56edd19100b31 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx @@ -1014,9 +1014,9 @@ describe('alert actions', () => { }); test('it uses ecs.Data.timestamp if one is provided', () => { - const ecsDataMock: Ecs = { + const ecsDataMock = { ...mockEcsDataWithAlert, - timestamp: '2020-03-20T17:59:46.349Z', + '@timestamp': '2020-03-20T17:59:46.349Z', }; const result = determineToAndFrom({ ecs: ecsDataMock }); @@ -1025,7 +1025,8 @@ describe('alert actions', () => { }); test('it uses current time timestamp if ecsData.timestamp is not provided', () => { - const { timestamp, ...ecsDataMock } = mockEcsDataWithAlert; + // @ts-ignore // TODO remove when EcsSecurityExtension has been cleaned https://github.com/elastic/kibana/issues/156879 + const { '@timestamp': timestamp, ...ecsDataMock } = mockEcsDataWithAlert; const result = determineToAndFrom({ ecs: ecsDataMock }); expect(result.from).toEqual('2020-03-01T17:54:46.349Z'); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 194e986ff68c2b..33174b9b2266bf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -27,6 +27,7 @@ import { ALERT_SUPPRESSION_END, ALERT_SUPPRESSION_DOCS_COUNT, ALERT_SUPPRESSION_TERMS, + TIMESTAMP, } from '@kbn/rule-data-utils'; import { lastValueFrom } from 'rxjs'; @@ -155,10 +156,13 @@ export const determineToAndFrom = ({ ecs }: { ecs: Ecs[] | Ecs }) => { const elapsedTimeRule = moment.duration( moment().diff(dateMath.parse(ruleFrom != null ? ruleFrom[0] : 'now-1d')) ); - const from = moment(ecsData.timestamp ?? new Date()) - .subtract(elapsedTimeRule) - .toISOString(); - const to = moment(ecsData.timestamp ?? new Date()).toISOString(); + + const alertTimestampEcsValue = getField(ecsData, TIMESTAMP); + const alertTimestamp = Array.isArray(alertTimestampEcsValue) + ? alertTimestampEcsValue[0] + : alertTimestampEcsValue; + const to = moment(alertTimestamp ?? new Date()).toISOString(); + const from = moment(to).subtract(elapsedTimeRule).toISOString(); return { to, from }; };