briandelmsft / SentinelAutomationModules

The Microsoft Sentinel Triage AssistanT (STAT) enables easy to create incident triage automation in Microsoft Sentinel
MIT License
201 stars 55 forks source link

[BUG] Base Module - custom entity array incorrectly processed #439

Closed AxelBornauw closed 3 months ago

AxelBornauw commented 7 months ago

Describe the bug Hello, I'm creating a custom playbook where I assist a Sentinel analyst by a Teams adaptive cards interface (just a demo project), by providing options like: 'Block user', 'Send user Teams msg' or 'Investigate entity'. In every case the analyst can choose entities from a drop down menu. When they choose users, they get added to an array, just like the 'Entities' dynamic Expression from the incident trigger. The array:

[
  {
    "id": "x",
    "name": "x",
    "type": "Microsoft.SecurityInsights/Entities"
    "kind": "Ip",
    "properties": {
      "address": "x.x.x.x",
      "friendlyName": "x.x.x.x"
    },
  }
]

However when I Initiate the Base Module and set the 'Entities' parameter to this array, it automatically converts the array to a string: Base module Input:

"body": {
        "AddAccountComments": false,
        "AddIPComments": false,
        "EnrichIPsWithGeoData": false,
        "Entities": "[{\"id\":\"x\",\"kind\":\"Ip\",\"name\":\"x\",\"properties\":{\"address\":\"x.x.x.x\",\"friendlyName\":\"x.x.x.x\"},\"type\":\"Microsoft.SecurityInsights/Entities\"}]",
        "IncidentARMId": "x",
        "WorkspaceId": "x"
    }

When i want to input a value in this parameter, the dynamic expression recommendations are also only my string variables. When I check the 'STAT-Coordinator', I found that the datatype of the 'Entities' field in the HTTP trigger is a string and not an array. Changing this value to an array doesnt do anything as well, and I'd also rather not change STAT modules.

"IncidentARMId": {
            "description": "Click here and select the Incident ARM ID object from the Dynamic content menu",
            "type": "string"
        }

However my knowledge of playbooks and STAT isn't significant enough to know if this has anything to do with it.

Module Name Base-Module

To Reproduce

  1. Create a custom array of objects (entities)
  2. Run the playbook
  3. Array gets turned into a string

Expected behavior The array gets processed properly instead of turning into a string.

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Is there something I'm doing wrong, or is this genuinely a bug?

briandelmsft commented 7 months ago

Hi @AxelBornauw thanks for the detailed information. What you're seeing is the result of an intentional decision. When you setup a Logic apps custom connector to pass an array which contains objects as the Entities array does, the GUI for the connector would effectively be asking you to input each object property individually, as opposed to asking you simply for 'Entities' it would be asking you for each array member, on a property by property basis. To actually input the entire arrays entity in that manner you'd need to hit a little button 'Switch to input entire array' which is not very obvious. Look at the scoring module as that is configured to input an array of objects

image

So that's why we decided to take it as a string to make it easier to input, the backend of STAT converts it back into an array for processing and we didn't really anticipate any user impact.

What I'm not clear about is how this is impacting you. The STAT processed data is outputted as an Accounts array, IPs array, Hosts array, etc with the enrichments from STAT. Or you can still use the Entities data straight from the incident trigger if you want that in array format.

briandelmsft commented 7 months ago

@AxelBornauw on a related note, the STAT v2 Preview Base Module inputs take the entire 'Body' of the incident (or alert, alerts are supported in v2) trigger. It doesn't explicitly ask for the Entities data, but the Entities are included as an array in the Body. So v2 does pass it as an array.

https://github.com/briandelmsft/SentinelAutomationModules/tree/statv2_preview/Deploy

AxelBornauw commented 7 months ago

@briandelmsft Thank you for the quick response. An incident has entities, for example: 'user a', 'user b' and ip 'x.x.x.x'. However in my playbook I give the Incident Responder the option to 'select' these entities on which he can do actions, like ''investigate entity", in which case I use some of your STAT modules. So I would have an array consisting of, for example only 'user a'. However when I pass through my "own array" of selected entities, it turns that array into a string. As opposed to inputting the "Entities" from the triggerBody. Hope you understand me better now!

Kind regards.

briandelmsft commented 7 months ago

@AxelBornauw thanks that's giving me a clearly picture of what you're doing, but I still don't quite understand the impact to you. You input an custom array of entities filtered from the incidents full entity list... that gets converted to a string to be passed to the back end... but the results get returned as objects/arrays not strings. Is something breaking? In my mind this string conversion is a backend operation that isn't impacting the outputs of STAT, like if we were to encode something in base64 prior to transmitting but returned data decoded.

Ultimately this type conversion is happening because of the Logic apps custom connector and the user experience was undesirable to us for passing this data as an array. You can however bypass the custom connector if you'd like and call the Base-Module directly via the Logic Apps connector 'Azure Logic Apps'. Ultimately, the Base-Module logic app is expecting an array. Take a look at how the 'STAT-Coordinator' Logic app routes the request from the custom connector to the base module, it shows an example of how to call the base module directly bypassing the customer connector. The downside to bypassing the custom connector though is the return data is not parsed automatically, but it can still be consumed by downstream modules.

image

Alternatively, you can also look at the STAT v2 preview which we pass the whole trigger body to STAT, including the entities which are passed as an array

briandelmsft commented 3 months ago

Please let me know if you have further questions on this