Query Details

Microsoft 365 Copilot - Exfiltration pattern (sensitive + cross-repo + large synthesis)

Copilot Exfiltration Pattern

Query

// Per-thread combo: DLP hit + >=5 distinct sites + >=50 total messages.
CopilotActivity
| where TimeGenerated > ago(6h)
| where RecordType == "CopilotInteraction"
| extend
    ThreadId = tostring(LLMEventData.ThreadId),
    DlpDeferred = tobool(LLMEventData.DLPEvaluationDeferred),
    InteractionMessages = array_length(LLMEventData.Messages)
| where isnotempty(ThreadId)
| mv-expand r = LLMEventData.AccessedResources
| extend
    SiteUrl = tostring(r.SiteUrl),
    ResourceType = tostring(r.Type),
    PolicyDetailsStr = tostring(r.PolicyDetails),
    HasPolicyHit = isnotempty(tostring(r.PolicyDetails))
        and tostring(r.PolicyDetails) !in ("[]", "{}", "null")
| summarize
    DlpHits = countif(HasPolicyHit or DlpDeferred),
    DistinctSites = dcount(SiteUrl),
    DistinctTypes = dcount(ResourceType),
    TotalMessages = sum(InteractionMessages),
    Interactions = dcount(strcat(tostring(TimeGenerated))),
    Sites = make_set(SiteUrl, 32),
    ResourceTypes = make_set(ResourceType, 16),
    Policies = make_set(PolicyDetailsStr, 16),
    AgentIds = make_set(AgentId, 4),
    AgentNames = make_set(AgentName, 4),
    Actors = make_set(ActorName, 4),
    ActorUserIds = make_set(ActorUserId, 4),
    ClientIPs = make_set(SrcIpAddr, 16),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by ThreadId, TenantId
| where DlpHits >= 1 and DistinctSites >= 5 and TotalMessages >= 50
| extend
    AgentId = tostring(AgentIds[0]),
    AgentName = tostring(AgentNames[0]),
    ActorName = tostring(Actors[0]),
    ActorUserId = tostring(ActorUserIds[0]),
    SrcIpAddr = tostring(ClientIPs[0])

Explanation

This query is designed to detect potential data exfiltration activities involving Microsoft 365 Copilot. Here's a simplified summary:

  1. Purpose: The query identifies suspicious patterns where sensitive data might be exfiltrated using Microsoft 365 Copilot. It looks for a combination of three specific signals:

    • A hit on a Data Loss Prevention (DLP) policy.
    • Access to multiple distinct repositories (at least 5 different sites).
    • A large number of messages (at least 50) in a single thread.
  2. How it Works:

    • The query examines Copilot activity over the past 6 hours.
    • It focuses on interactions where there is a DLP policy hit or evaluation is deferred.
    • It checks if the activity involves accessing resources from at least 5 different sites and involves at least 50 messages in total.
    • If these conditions are met, it flags the activity as potentially malicious.
  3. Limitations: The query only uses structural data from Copilot interactions and cannot detect explicit actions like exporting or forwarding data because it doesn't analyze the actual content of prompts or responses.

  4. Severity and Actions:

    • The severity of this detection is marked as high.
    • If the conditions are met, an incident is created for further investigation.
    • The query runs every hour and looks back at the past 6 hours of data.
  5. Configuration:

    • The query is enabled by default and is part of a scheduled task.
    • It groups incidents by account to help identify patterns related to specific users.

Overall, this query is a proactive measure to monitor and alert on potential data exfiltration activities using Microsoft 365 Copilot, helping organizations protect sensitive information.

Details

David Alonso profile picture

David Alonso

Released: May 20, 2026

Tables

CopilotActivity

Keywords

CopilotActivityThreadResourceSitePolicyMessageAgentActorUserIPAccountApplicationAlertIncident

Operators

ago==tostringtoboolarray_lengthisnotemptymv-expand!insummarizecountifdcountsummake_setminmaxby>=extend

Severity

High

Tactics

CollectionExfiltration

MITRE Techniques

Frequency: PT1H

Period: PT6H

Actions

GitHub