OAuth application consent to high-risk permission scope
Description
Identifies OAuth application consent events where high-risk permissions such as Directory.ReadWrite.All or RoleManagement.ReadWrite.Directory were granted to apps with no prior tenant consent history in the preceding 90 days.
Query · kql
let timeframe = 1d;
let lookback = 90d;
let HighRiskScopes = dynamic([
"RoleManagement.ReadWrite.Directory",
"Application.ReadWrite.All",
"AppRoleAssignment.ReadWrite.All",
"Directory.ReadWrite.All",
"User.ReadWrite.All",
"Mail.ReadWrite",
"Mail.Send",
"Files.ReadWrite.All",
"full_access_as_app"
]);
let KnownApps =
AuditLogs
| where TimeGenerated >= ago(timeframe + lookback) and TimeGenerated < ago(timeframe)
| where OperationName =~ "Consent to application"
| extend AppId = tostring(TargetResources[0].id)
| distinct AppId;
AuditLogs
| where TimeGenerated >= ago(timeframe)
| where OperationName =~ "Consent to application"
| where Result =~ "success"
| extend AppId = tostring(TargetResources[0].id)
| extend AppName = tostring(TargetResources[0].displayName)
| extend ActorUpn = tostring(InitiatedBy.user.userPrincipalName)
| extend ActorApp = tostring(InitiatedBy.app.displayName)
| extend Actor = iff(isnotempty(ActorUpn), ActorUpn, ActorApp)
| extend ActorIp = iff(
isnotempty(tostring(InitiatedBy.user.ipAddress)),
tostring(InitiatedBy.user.ipAddress),
tostring(InitiatedBy.app.ipAddress))
| mv-expand ModProp = TargetResources[0].modifiedProperties
| where tostring(ModProp.displayName) =~ "ConsentAction.Permissions"
| extend GrantedPermissions = tostring(ModProp.newValue)
| where GrantedPermissions has_any (HighRiskScopes)
| join kind=leftanti KnownApps on AppId
| extend AccountName = iff(Actor has "@", tostring(split(Actor, "@")[0]), Actor)
| extend AccountUPNSuffix = iff(Actor has "@", tostring(split(Actor, "@")[1]), "")
| project TimeGenerated, AppName, AppId, GrantedPermissions, Actor,
AccountName, AccountUPNSuffix, ActorIp, CorrelationId
| sort by TimeGenerated desc