briandelmsft / STAT-Function

Azure Function for the Microsoft Sentinel Triage AssistanT (STAT)
https://aka.ms/mstat
MIT License
8 stars 1 forks source link

[BUG] Cannot obtain a token for MDCA when multitenant JSON is used #49

Closed piaudonn closed 7 months ago

piaudonn commented 8 months ago

When the base module takes a json in parameter that specifies the MDCAUrl, the MDCA module fails to get a token.

https://github.com/briandelmsft/STAT-Function/blob/f02a8ca826888cede5fda99ca8e955f65c73ca24/shared/rest.py#L50

It is due to the fact we set the tenant ID to the MDCAUrl for token request.

{
    "statusCode": 400,
    "headers": {
        "Transfer-Encoding": "chunked",
        "Date": "Wed, 08 Nov 2023 17:02:39 GMT",
        "Content-Type": "application/json",
        "Content-Length": "2311"
    },
    "body": {
        "Error": "Module processing failed, an unknown exception has occurred.",
        "InvocationId": "6cdf5775-02dc-4e35-b6fc-8fe6a78717ce",
        "Traceback": [
            "Traceback (most recent call last):\n",
            "  File \"/home/site/wwwroot/modules/__init__.py\", line 19, in main\n    return_data = coordinator.initiate_module(module_name=module_name, req_body=req_body)\n",
            "  File \"/home/site/wwwroot/shared/coordinator.py\", line 21, in initiate_module\n    return_data = mdca.execute_mdca_module(req_body)\n",
            "  File \"/home/site/wwwroot/modules/mdca.py\", line 31, in execute_mdca_module\n    mdcaresults = json.loads(rest.rest_call_get(base_object, api='mdca', path=path).content)\n",
            "  File \"/home/site/wwwroot/shared/rest.py\", line 101, in rest_call_get\n    token = token_cache(base_module, api)\n",
            "  File \"/home/site/wwwroot/shared/rest.py\", line 51, in token_cache\n    token_expiration_check(api, stat_token.get(tenant,{}).get('mdcatoken'), tenant)\n",
            "  File \"/home/site/wwwroot/shared/rest.py\", line 57, in token_expiration_check\n    acquire_token(api, tenant)\n",
            "  File \"/home/site/wwwroot/shared/rest.py\", line 91, in acquire_token\n    stat_token[tenant]['mdcatoken'] = cred.get_token(\"05a65629-4c1b-48c1-a78b-804c4abdd4af/.default\", tenant_id=tenant)\n",
            "  File \"/home/site/wwwroot/.python_packages/lib/site-packages/azure/identity/_credentials/default.py\", line 225, in get_token\n    token = super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)\n",
            "  File \"/home/site/wwwroot/.python_packages/lib/site-packages/azure/identity/_credentials/chained.py\", line 123, in get_token\n    raise ClientAuthenticationError(message=message)\n",
            "azure.core.exceptions.ClientAuthenticationError: DefaultAzureCredential failed to retrieve a token from the included credentials.\nAttempted credentials:\n\tEnvironmentCredential: Authentication failed: Unable to get authority configuration for https://login.microsoftonline.com/tenant.us3.portal.cloudappsecurity.com. Authority would typically be in a format of https://login.microsoftonline.com/your_tenant Also please double check your tenant name or GUID is correct.\nTo mitigate this issue, please refer to the troubleshooting guidelines here at https://aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.\n"
        ]
    }
}

Considering that it is highly unlikely to query a MDCA tenant different that the one used for the rest of Defender, I suggest the following modification:

tenant = base_module.MultiTenantConfig.get('MDCAUrl', base_module.MultiTenantConfig.get('TenantId', default_tenant))

becomes

tenant = base_module.MultiTenantConfig.get('M365DTenantId', base_module.MultiTenantConfig.get('TenantId', default_tenant))