[Security Solution][Admin][Responder] Disable Reponder option in action menu if processes capabilities are not supported (#136904)

This commit is contained in:
Candace Park 2022-07-25 23:58:44 -04:00 committed by GitHub
parent 0154f75445
commit 4227348b95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 5 deletions

View file

@ -73,3 +73,4 @@ export const failedFleetActionErrorCode = '424';
export const ENDPOINT_DEFAULT_PAGE = 0;
export const ENDPOINT_DEFAULT_PAGE_SIZE = 10;
export const RESPONDER_CAPABILITIES = ['kill_process', 'suspend_process', 'running_processes'];

View file

@ -6,7 +6,6 @@
*/
import type seedrandom from 'seedrandom';
import semverLte from 'semver/functions/lte';
import { assertNever } from '@kbn/std';
import type {
GetAgentPoliciesResponseItem,
@ -461,8 +460,7 @@ export class EndpointDocGenerator extends BaseDataGenerator {
const hostName = this.randomHostname();
const isIsolated = this.randomBoolean(0.3);
const agentVersion = this.randomVersion();
const minCapabilitiesVersion = '7.15.0';
const capabilities = ['isolation'];
const capabilities = ['isolation', 'kill_process', 'suspend_process', 'running_processes'];
const agentId = this.seededUUIDv4();
return {
@ -496,7 +494,7 @@ export class EndpointDocGenerator extends BaseDataGenerator {
state: {
isolation: isIsolated,
},
capabilities: semverLte(minCapabilitiesVersion, agentVersion) ? capabilities : [],
capabilities,
},
};
}

View file

@ -0,0 +1,17 @@
/*
* 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 { RESPONDER_CAPABILITIES } from '../../../../common/endpoint/constants';
import type { HostMetadata, MaybeImmutable } from '../../../../common/endpoint/types';
export const useDoesEndpointSupportResponder = (
endpointMetadata: MaybeImmutable<HostMetadata> | undefined
): boolean => {
return RESPONDER_CAPABILITIES.every((capability) =>
endpointMetadata?.Endpoint.capabilities?.includes(capability)
);
};

View file

@ -28,3 +28,11 @@ export const UPDATE_ALERT_STATUS_FAILED_DETAILED = (updated: number, conflicts:
defaultMessage: `{ updated } {updated, plural, =1 {alert was} other {alerts were}} updated successfully, but { conflicts } failed to update
because { conflicts, plural, =1 {it was} other {they were}} already being modified.`,
});
export const UPGRADE_ENDPOINT_FOR_RESPONDER = i18n.translate(
'xpack.securitySolution.endpoint.actions.disabledResponder.tooltip',
{
defaultMessage:
'The current version of the Agent does not support this feature. Upgrade your Agent through Fleet to use this feature and new response actions such as killing and suspending processes.',
}
);

View file

@ -12,6 +12,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { useGetEndpointDetails, useWithShowEndpointResponder } from '../../../management/hooks';
import { HostStatus } from '../../../../common/endpoint/types';
import { useDoesEndpointSupportResponder } from '../../../common/hooks/endpoint/use_does_endpoint_support_responder';
import { UPGRADE_ENDPOINT_FOR_RESPONDER } from '../../../common/translations';
export const NOT_FROM_ENDPOINT_HOST_TOOLTIP = i18n.translate(
'xpack.securitySolution.endpoint.detections.takeAction.responseActionConsole.notSupportedTooltip',
@ -43,11 +45,18 @@ export const ResponderContextMenuItem = memo<ResponderContextMenuItemProps>(
error,
} = useGetEndpointDetails(endpointId, { enabled: Boolean(endpointId) });
const isResponderCapabilitiesEnabled = useDoesEndpointSupportResponder(
endpointHostInfo?.metadata
);
const [isDisabled, tooltip]: [disabled: boolean, tooltip: ReactNode] = useMemo(() => {
if (!endpointId) {
return [true, NOT_FROM_ENDPOINT_HOST_TOOLTIP];
}
if (!isResponderCapabilitiesEnabled) {
return [true, UPGRADE_ENDPOINT_FOR_RESPONDER];
}
// Still loading Endpoint host info
if (isFetching) {
return [true, LOADING_ENDPOINT_DATA_TOOLTIP];
@ -64,7 +73,13 @@ export const ResponderContextMenuItem = memo<ResponderContextMenuItemProps>(
}
return [false, undefined];
}, [endpointHostInfo?.host_status, endpointId, error, isFetching]);
}, [
endpointHostInfo?.host_status,
endpointId,
error,
isFetching,
isResponderCapabilitiesEnabled,
]);
const handleResponseActionsClick = useCallback(() => {
if (endpointHostInfo) showEndpointResponseActionsConsole(endpointHostInfo.metadata);

View file

@ -21,6 +21,8 @@ import type { ContextMenuItemNavByRouterProps } from '../../../../components/con
import { isEndpointHostIsolated } from '../../../../../common/utils/validators';
import { useLicense } from '../../../../../common/hooks/use_license';
import { isIsolationSupported } from '../../../../../../common/endpoint/service/host_isolation/utils';
import { useDoesEndpointSupportResponder } from '../../../../../common/hooks/endpoint/use_does_endpoint_support_responder';
import { UPGRADE_ENDPOINT_FOR_RESPONDER } from '../../../../../common/translations';
interface Options {
isEndpointList: boolean;
@ -43,6 +45,7 @@ export const useEndpointActionItems = (
'responseActionsConsoleEnabled'
);
const canAccessResponseConsole = useUserPrivileges().endpointPrivileges.canAccessResponseConsole;
const isResponderCapabilitiesEnabled = useDoesEndpointSupportResponder(endpointMetadata);
return useMemo<ContextMenuItemNavByRouterProps[]>(() => {
if (endpointMetadata) {
@ -125,6 +128,7 @@ export const useEndpointActionItems = (
'data-test-subj': 'console',
icon: 'console',
key: 'consoleLink',
disabled: !isResponderCapabilitiesEnabled,
onClick: (ev: React.MouseEvent) => {
ev.preventDefault();
showEndpointResponseActionsConsole(endpointMetadata);
@ -135,6 +139,9 @@ export const useEndpointActionItems = (
defaultMessage="Launch responder"
/>
),
toolTipContent: !isResponderCapabilitiesEnabled
? UPGRADE_ENDPOINT_FOR_RESPONDER
: '',
},
]
: []),
@ -257,5 +264,6 @@ export const useEndpointActionItems = (
isResponseActionsConsoleEnabled,
showEndpointResponseActionsConsole,
options?.isEndpointList,
isResponderCapabilitiesEnabled,
]);
};