Skip to content

Commit 02148cf

Browse files
authored
[EDR Workflows] Validate runscript response action against MDE action (#237109)
1 parent 668aee1 commit 02148cf

File tree

3 files changed

+638
-23
lines changed

3 files changed

+638
-23
lines changed

x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/microsoft/defender/endpoint/mocks.ts

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import type {
1818
MicrosoftDefenderEndpointMachine,
1919
MicrosoftDefenderEndpointMachineAction,
2020
MicrosoftDefenderGetLibraryFilesResponse,
21+
MicrosoftDefenderEndpointRunScriptParams,
22+
MicrosoftDefenderEndpointGetActionsParams,
2123
} from '@kbn/stack-connectors-plugin/common/microsoft_defender_endpoint/types';
2224
import { merge } from 'lodash';
2325
import { applyEsClientSearchMock } from '../../../../../../mocks/utils.mock';
@@ -77,6 +79,17 @@ const createMsDefenderClientConstructorOptionsMock = () => {
7779
const createMsConnectorActionsClientMock = (): ActionsClientMock => {
7880
const client = responseActionsClientMock.createConnectorActionsClient();
7981

82+
/**
83+
* Tracks the last runscript action to enable dynamic mock responses.
84+
* When GET_ACTIONS is called with a matching action ID, the mock returns
85+
* the captured script details to simulate MDE's behavior.
86+
*/
87+
const lastAction = {
88+
lastRunScriptActionId: '5382f7ea-7557-4ab7-9782-d50480024a4e',
89+
lastRunScriptScriptName: 'test-script.ps1',
90+
lastRunScriptComment: 'Action triggered from Elastic Security (action id: test-action-id)',
91+
};
92+
8093
(client.getAll as jest.Mock).mockImplementation(async () => {
8194
const result: ConnectorWithExtraFindData[] = [
8295
// return a MS connector
@@ -92,6 +105,7 @@ const createMsConnectorActionsClientMock = (): ActionsClientMock => {
92105
(client.execute as jest.Mock).mockImplementation(
93106
async (options: Parameters<typeof client.execute>[0]) => {
94107
const subAction = options.params.subAction;
108+
const subActionParams = options.params.subActionParams;
95109

96110
// Mocks for the different connector methods
97111
switch (subAction) {
@@ -116,20 +130,62 @@ const createMsConnectorActionsClientMock = (): ActionsClientMock => {
116130
});
117131

118132
case MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_ACTIONS:
133+
// Dynamic response based on requested action ID
134+
// If the requested action ID matches the last runscript action, return a RunScript action
135+
// Otherwise, return a generic machine action (for isolate/release/cancel)
136+
const getActionsParams = subActionParams as MicrosoftDefenderEndpointGetActionsParams;
137+
const requestedActionId = getActionsParams.id?.[0];
138+
const isRunScriptAction = requestedActionId === lastAction.lastRunScriptActionId;
139+
119140
return responseActionsClientMock.createConnectorActionExecuteResponse({
120141
data: {
121142
'@odata.context': 'some-context',
122143
'@odata.count': 1,
123144
total: 1,
124145
page: 1,
125-
pageSize: 0,
126-
value: [createMicrosoftMachineActionMock()],
146+
pageSize: 1,
147+
value: isRunScriptAction
148+
? [
149+
createMicrosoftMachineActionMock({
150+
id: lastAction.lastRunScriptActionId,
151+
type: 'LiveResponse',
152+
status: 'InProgress',
153+
requestorComment: lastAction.lastRunScriptComment,
154+
commands: [
155+
{
156+
index: 0,
157+
startTime: new Date(Date.now() - 10000).toISOString(),
158+
endTime: new Date().toISOString(),
159+
commandStatus: 'InProgress',
160+
errors: [],
161+
command: {
162+
type: 'RunScript',
163+
params: [
164+
{ key: 'ScriptName', value: lastAction.lastRunScriptScriptName },
165+
],
166+
},
167+
},
168+
],
169+
}),
170+
]
171+
: [createMicrosoftMachineActionMock()],
127172
},
128173
});
129174

130175
case MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.RUN_SCRIPT:
176+
// Capture values for subsequent GET_ACTIONS calls to enable validation testing
177+
const runScriptParams = subActionParams as MicrosoftDefenderEndpointRunScriptParams;
178+
const actionId = '5382f7ea-7557-4ab7-9782-d50480024a4e';
179+
lastAction.lastRunScriptActionId = actionId;
180+
lastAction.lastRunScriptScriptName =
181+
runScriptParams.parameters?.scriptName || 'test-script.ps1';
182+
lastAction.lastRunScriptComment = runScriptParams.comment || 'test comment';
183+
131184
return responseActionsClientMock.createConnectorActionExecuteResponse({
132-
data: createMicrosoftMachineActionMock({ type: 'LiveResponse' }),
185+
data: createMicrosoftMachineActionMock({
186+
type: 'LiveResponse',
187+
id: actionId,
188+
}),
133189
});
134190

135191
case MICROSOFT_DEFENDER_ENDPOINT_SUB_ACTION.GET_LIBRARY_FILES:

0 commit comments

Comments
 (0)