[Security Solution][Endpoint] Show tooltip icon on processes response console command for SentinelOne Windows hosts (#201030)

## Summary

- Displays a tooltip icon for the `processes` command on the Response
Console for SentinelOne Windows hosts indicating that `processes` is not
supported on those types of hosts
This commit is contained in:
Paul Tavares 2024-12-02 16:59:35 -05:00 committed by GitHub
parent a6b3743e00
commit 40905c14ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 80 additions and 10 deletions

View file

@ -73,6 +73,7 @@ describe('When using execute action from response actions console', () => {
endpointAgentId: 'a.b.c',
endpointCapabilities: [...capabilities],
endpointPrivileges,
platform: 'linux',
}),
},
};

View file

@ -71,6 +71,7 @@ describe('When using get-file action from response actions console', () => {
endpointAgentId: 'a.b.c',
endpointCapabilities: [...ENDPOINT_CAPABILITIES],
endpointPrivileges,
platform: 'linux',
};
render = async (capabilities: EndpointCapabilities[] = [...ENDPOINT_CAPABILITIES]) => {

View file

@ -59,6 +59,7 @@ describe('When using processes action from response actions console', () => {
canSuspendProcess: true,
canGetRunningProcesses: true,
},
platform: 'linux',
});
};

View file

@ -67,6 +67,7 @@ describe('When using isolate action from response actions console', () => {
loading: false,
canIsolateHost: true,
},
platform: 'linux',
}),
},
};

View file

@ -63,6 +63,7 @@ describe.skip('When using the kill-process action from response actions console'
canSuspendProcess: true,
canGetRunningProcesses: true,
},
platform: 'linux',
});
};

View file

@ -46,6 +46,7 @@ const prepareTest = () => {
canUnIsolateHost: true,
loading: false,
},
platform: 'linux',
}),
},
};

View file

@ -83,6 +83,7 @@ describe('When using scan action from response actions console', () => {
endpointAgentId: 'agent-a',
endpointCapabilities: [...ENDPOINT_CAPABILITIES],
endpointPrivileges,
platform: 'linux',
};
render = async (capabilities: EndpointCapabilities[] = [...ENDPOINT_CAPABILITIES]) => {

View file

@ -111,6 +111,7 @@ describe.skip('When using processes action from response actions console', () =>
...getEndpointAuthzInitialState(),
loading: false,
},
platform: 'linux',
}),
},
};

View file

@ -73,6 +73,7 @@ describe('When using the suspend-process action from response actions console',
canSuspendProcess: true,
canGetRunningProcesses: true,
},
platform: 'linux',
}),
},
};

View file

@ -88,6 +88,7 @@ describe.skip('When using `upload` response action', () => {
endpointAgentId: 'a.b.c',
endpointCapabilities,
endpointPrivileges,
platform: 'linux',
}),
},
};

View file

@ -153,6 +153,8 @@ export interface GetEndpointConsoleCommandsOptions {
/** Applicable only for Endpoint Agents */
endpointCapabilities: ImmutableArray<string>;
endpointPrivileges: EndpointPrivileges;
/** Host's platform: windows, linux, macos */
platform: string;
}
export const getEndpointConsoleCommands = ({
@ -160,6 +162,7 @@ export const getEndpointConsoleCommands = ({
agentType,
endpointCapabilities,
endpointPrivileges,
platform,
}: GetEndpointConsoleCommandsOptions): CommandDefinition[] => {
const featureFlags = ExperimentalFeaturesService.get();
@ -523,7 +526,7 @@ export const getEndpointConsoleCommands = ({
switch (agentType) {
case 'sentinel_one':
return adjustCommandsForSentinelOne({ commandList: consoleCommands });
return adjustCommandsForSentinelOne({ commandList: consoleCommands, platform });
case 'crowdstrike':
return adjustCommandsForCrowdstrike({ commandList: consoleCommands });
default:
@ -543,8 +546,10 @@ const disableCommand = (command: CommandDefinition, agentType: ResponseActionAge
/** @private */
const adjustCommandsForSentinelOne = ({
commandList,
platform,
}: {
commandList: CommandDefinition[];
platform: string;
}): CommandDefinition[] => {
const featureFlags = ExperimentalFeaturesService.get();
const isKillProcessEnabled = featureFlags.responseActionsSentinelOneKillProcessEnabled;
@ -580,6 +585,28 @@ const adjustCommandsForSentinelOne = ({
)
) {
disableCommand(command, 'sentinel_one');
} else {
// processes is not currently supported for Windows hosts
if (command.name === 'processes' && platform.toLowerCase() === 'windows') {
const message = i18n.translate(
'xpack.securitySolution.consoleCommandsDefinition.sentineloneProcessesWindowRestriction',
{
defaultMessage:
'Processes command is not currently supported for SentinelOne hosts running on Windows',
}
);
command.helpDisabled = true;
command.about = getCommandAboutInfo({
aboutInfo: command.about,
isSupported: false,
dataTestSubj: 'sentineloneProcessesWindowsWarningTooltip',
tooltipContent: message,
});
command.validate = () => {
return message;
};
}
}
return command;

View file

@ -6,6 +6,7 @@
*/
import React from 'react';
import type { EuiToolTipProps } from '@elastic/eui';
import { EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -17,23 +18,28 @@ const UNSUPPORTED_COMMAND_INFO = i18n.translate(
}
);
const DisabledTooltip = React.memo(() => {
return <EuiIconTip content={UNSUPPORTED_COMMAND_INFO} type="warning" color="danger" />;
});
DisabledTooltip.displayName = 'DisabledTooltip';
export const getCommandAboutInfo = ({
aboutInfo,
isSupported,
tooltipContent = UNSUPPORTED_COMMAND_INFO,
dataTestSubj,
}: {
aboutInfo: string;
aboutInfo: React.ReactNode;
isSupported: boolean;
tooltipContent?: EuiToolTipProps['content'];
dataTestSubj?: string;
}) => {
return isSupported ? (
aboutInfo
) : (
<>
{aboutInfo} <DisabledTooltip />
{aboutInfo}{' '}
<EuiIconTip
anchorProps={{ 'data-test-subj': dataTestSubj }}
content={tooltipContent}
type="warning"
color="danger"
/>
</>
);
};

View file

@ -52,6 +52,7 @@ describe('When displaying Endpoint Response Actions', () => {
endpointAgentId: '123',
endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [],
endpointPrivileges: getEndpointPrivilegesInitialStateMock(),
platform: 'linux',
});
});
@ -89,6 +90,8 @@ describe('When displaying Endpoint Response Actions', () => {
responseActionsCrowdstrikeManualHostIsolationEnabled: true,
responseActionsSentinelOneV1Enabled: true,
responseActionsSentinelOneGetFileEnabled: true,
responseActionsSentinelOneKillProcessEnabled: true,
responseActionsSentinelOneProcessesEnabled: true,
});
commands = getEndpointConsoleCommands({
@ -96,6 +99,7 @@ describe('When displaying Endpoint Response Actions', () => {
endpointAgentId: '123',
endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [],
endpointPrivileges: getEndpointPrivilegesInitialStateMock(),
platform: 'linux',
});
});
@ -110,13 +114,34 @@ describe('When displaying Endpoint Response Actions', () => {
});
it('should display response action commands in the help panel in expected order', () => {
render({ commands });
const { queryByTestId } = render({ commands });
consoleSelectors.openHelpPanel();
const commandsInPanel = helpPanelSelectors.getHelpCommandNames(
HELP_GROUPS.responseActions.label
);
expect(commandsInPanel).toEqual(['isolate', 'release', 'get-file --path']);
expect(commandsInPanel).toEqual([
'isolate',
'release',
'processes',
'kill-process --processName',
'get-file --path',
]);
expect(queryByTestId('sentineloneProcessesWindowsWarningTooltip')).toBeNull();
});
it('should display warning icon on processes command if host is running on windows', () => {
commands = getEndpointConsoleCommands({
agentType: 'sentinel_one',
endpointAgentId: '123',
endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [],
endpointPrivileges: getEndpointPrivilegesInitialStateMock(),
platform: 'windows',
});
const { getByTestId } = render({ commands });
consoleSelectors.openHelpPanel();
expect(getByTestId('sentineloneProcessesWindowsWarningTooltip')).not.toBeNull();
});
});
@ -130,6 +155,7 @@ describe('When displaying Endpoint Response Actions', () => {
endpointAgentId: '123',
endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [],
endpointPrivileges: getEndpointPrivilegesInitialStateMock(),
platform: 'linux',
});
});

View file

@ -71,6 +71,7 @@ export const useWithShowResponder = (): ShowResponseActionsConsole => {
endpointAgentId: agentId,
endpointCapabilities: capabilities,
endpointPrivileges,
platform,
}),
'data-test-subj': `${agentType}ResponseActionsConsole`,
storagePrefix: 'xpack.securitySolution.Responder',