An API that connects multiple Microsoft services, enabling data access and automation across platforms
Microsoft Graph API - Security Alerts - Unexpected behavior when filtering by vendorInformation/provider
Hi,
Recently I have been doing a development project that was using the Microsoft Graph API, concretely the Security endpoint.
The main objective of this development is to extract a list of alerts using that API (which is having version 1.0).
The requirements I have are the following ones:
- To be able to establish a specific date as a starting point (for example
2021-01-01T00:00:00.0000000Z). - To resend each received "page" as soon as possible for storing the less possible information in the extractor application (memory resource usage).
- To resend the alerts sorted by the
eventDateTimefield. - After the first retrieving, some other secondary ones will be executed for gathering any possible new created alert since the previously saved timestamps
I have tried several approaches and finally, I decided to use the “Main” + “Vendor” request types.
1- The following “main” request has been used for retrieving the whole list of the available vendors since a specific timestamp:
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-01-01T00:00:00.0000000Z&$orderby=eventDateTime+asc&$select=vendorInformation,eventDateTime&$top=10
Note 1: Don’t pay attention to the URL encoding, I have set the values unencoded only in this text, not in the application.
Note 2: I know that using $top=1 would be enough for knowing the number of existing vendors but I have used $top=10 because there are some vendors that are having several different vendor information (at least is happening with one of them, Microsoft Defender ATP and Microsoft 365 Defender).
2- After processing only the results from the first page, they have been programmatically detected 6 different unique vendors:
[
{
"vendor": "Microsoft", "provider": "Azure Advanced Threat Protection", "subProvider": null
},
{
"vendor": "Microsoft", "provider": "Microsoft Defender ATP", "subProvider": "MicrosoftDefenderATP"
},
{
"vendor": "Microsoft", "provider": "Microsoft 365 Defender", "subProvider": "Microsoft365Defender"
},
{
"vendor": "Microsoft", "provider": "IPC", "subProvider": null
},
{
"vendor": "Microsoft", "provider": "Office 365 Security and Compliance", "subProvider": null
},
{
"vendor": "Microsoft", "provider": "MCAS", "subProvider": null
}
]
I have done some modifications for knowing the number of alerts grouped by “unique vendor” and these are the detected results using only the “main” request:
{vendor}.{provider}.{subProvider}: <detected items>
Microsoft.Azure Advanced Threat Protection.None: 13
Microsoft.Microsoft Defender ATP.MicrosoftDefenderATP: 489
Microsoft.Microsoft 365 Defender.Microsoft365Defender: 24
Microsoft.IPC.None: 7
Microsoft.Office 365 Security and Compliance.None: 1000
Microsoft.MCAS.None: 81
3- Then per each detected unique provider, I launched several secondary requests, this is the request template:
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-01-01T00:00:00.0000000Z+AND+vendorInformation/provider+eq+'{provider}'&$orderby=eventDateTime+asc&$top=200
Note: Don’t pay attention to the URL encoding, I have set the values unencoded only in this text, not in the application.
4- The previous secondary queries are having different behaviors depending on the vendorInformation/provider filter used:
{vendor}.{provider}.{subProvider}: <items> => <comments>
Microsoft.Azure Advanced Threat Protection.None: 13 => Alerts properly sorted by the eventDateTime field
Microsoft.Microsoft Defender ATP.MicrosoftDefenderATP: 513 => Alerts properly sorted by the eventDateTime field
Microsoft.Microsoft 365 Defender.Microsoft365Defender: 0 => It seems that this provider data can not used in the $filter parameter
Microsoft.IPC.None: 7 => Alerts properly sorted by the eventDateTime field
Microsoft.Office 365 Security and Compliance.None: 1000 => Alerts properly sorted by the eventDateTime field
Microsoft.MCAS.None: 81 => Alerts properly sorted by the eventDateTime field
The requests done using the filter vendorInformation/provider eq 'Microsoft Defender ATP' is responding alerts that are having two different vendorInformation values:
{
"vendor": "Microsoft",
"provider": "Microsoft Defender ATP",
"subProvider": "MicrosoftDefenderATP"
},
{
"vendor": "Microsoft",
"provider": "Microsoft 365 Defender",
"subProvider": "Microsoft365Defender"
}
5- After retrieving all alerts using the different secondary requests (using the filter by vendor), I have determined the last timestamp value by each vendor, the results are in the following table:
{vendor}.{provider}.{subProvider}: <last alert timestamp>
Microsoft.Azure Advanced Threat Protection.None: 2021-12-21T11:33:49.9578360Z
Microsoft.Microsoft Defender ATP.MicrosoftDefenderATP: 2021-12-22T06:48:49.5196343Z
Microsoft.IPC.None: 2021-12-16T04:03:42.4845711Z
Microsoft.Office 365 Security and Compliance.None: 2021-12-22T15:37:00.0000000Z
Microsoft.MCAS.None: 2021-12-22T03:41:25.4170000Z
6- After a specific amount of time, let’s say 5 minutes, they will be re-launched the secondary requests for knowing if any other alerts have been created since the saved timestamps, and I expected to obtain always at least one alert by each new request (the same alert that was the last one from the previous request), and here I have observed a very strange behavior:
Note: Don’t pay attention to the URL encoding, I have set the values unencoded only in this text, not in the application.
<request> => <comment>
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-12-21T11:33:49.9578360Z+AND+vendorInformation/provider+eq+'Azure Advanced Threat Protection'&$orderby=eventDateTime+asc&$top=200 => Wrong result, obtained 0 items in the response and it was expected at least 1
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-12-22T06:48:49.5196343Z+AND+vendorInformation/provider+eq+'Microsoft Defender ATP'&$orderby=eventDateTime+asc&$top=200 => Received 1 items, the same one that was the last in the previous request, so it’s OK
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-12-16T04:03:42.4845711Z+AND+vendorInformation/provider+eq+'IPC'&$orderby=eventDateTime+asc&$top=200 => Wrong result, obtained 0 items in the response and it was expected at least 1
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-12-22T15:37:00.0000000Z+AND+vendorInformation/provider+eq+'Office 365 Security and Compliance'&$orderby=eventDateTime+asc&$top=200 => Received 1 items, the same one that was the last in the previous request, so it’s OK
https://graph.microsoft.com/v1.0/security/alerts?$count=true&$filter=eventDateTime+ge+2021-12-22T03:41:25.4170000Z+AND+vendorInformation/provider+eq+'MCAS'&$orderby=eventDateTime+asc&$top=200 => Wrong result, obtained 0 items in the response and it was expected at least 1
Note: I have tried to do some debugging and change manually a bit the values of the failing queries and it seems that if I reduce the timestamps in 1 * 10^7 (the last decimal position), the alerts I was expecting are coming, but this is not the expected behavior because it’s being used the operator greater or equal than and not greater than.
So, long story short:
1. When filtering the alerts by the vendorInformation/provider property the results are not having only values from the filtered used.
2. When filtering the alerts by the vendorInformation/provider and eventDateTime properties the operator greater or equal than is not working properly.
This lack of consistency causes me a loss of confidence in that I am receiving all existing alerts.