Query Details

Copilot Studio - Session context contamination across a conversation

Copilot Studio Session Context Contamination

Query

let injectionMarkers = dynamic([
    "ignore previous instructions","disregard previous","you are now",
    "developer mode","do anything now","reveal your system prompt",
    "bypass your rules","forget the previous","new instructions",
    "from now on you","store this and remember","next time the user asks"
]);
let sensitiveConnectors = dynamic([
    "office365","sendemail","sendmail","outlook","exchange",
    "http","webhook","azuread","azure","sql","dataverse",
    "sharepoint","onedrive","powershell","function","automate",
    "logicapp","graph","keyvault","blob","storage"
]);
let safeHostSuffixes = dynamic([
    "microsoft.com","office.com","office365.com","sharepoint.com",
    "microsoftonline.com","windows.net","azure.com","azureedge.net",
    "live.com","bing.com","msn.com","dynamics.com","powerplatform.com"
]);
let turns =
    AppEvents
    | where TimeGenerated > ago(2h)
    | where Name == "BotMessageReceived"
    | extend ConvId = tostring(Properties["conversationId"]),
             Text   = tolower(tostring(Properties["text"])),
             ChannelId = tostring(Properties["channelId"])
    | where isnotempty(Text);
let convBounds =
    turns
    | summarize Turns = count(),
                Start = min(TimeGenerated),
                End   = max(TimeGenerated),
                AnyUser = take_any(UserId),
                AnyIp   = take_any(ClientIP),
                AnyChannel = take_any(ChannelId)
            by ConvId
    | where Turns >= 5;
let early =
    turns
    | join kind=inner convBounds on ConvId
    | extend RangeMs = max_of(datetime_diff('millisecond', End, Start), 1)
    | extend OffMs   = datetime_diff('millisecond', TimeGenerated, Start)
    | extend Quartile = min_of(toint(OffMs * 4 / RangeMs), 3)
    | where Quartile == 0
    | extend Host = tolower(extract(@"https?://([A-Za-z0-9.\-]+)", 1, Text))
    | extend HasInjection = Text has_any (injectionMarkers);
let earlyUrl =
    early
    | where isnotempty(Host)
    | where not(Host has_any (safeHostSuffixes))
    | summarize UrlHits = count(), UntrustedHosts = make_set(Host, 16) by ConvId;
let earlyInj =
    early
    | summarize InjHits = countif(HasInjection) by ConvId;
let lateActs =
    AppDependencies
    | where TimeGenerated > ago(2h)
    | where AppRoleName == "Microsoft Copilot Studio" or DependencyType == "Connector"
    | extend ConvId   = tostring(Properties["conversationId"]),
             MatchKey = tolower(strcat(Name, " ", Target))
    | where MatchKey has_any (sensitiveConnectors)
    | summarize SensitiveCalls  = count(),
                Connectors      = make_set(Name, 8),
                Targets         = make_set(Target, 16),
                LastSeen        = max(TimeGenerated),
                FirstSensitive  = min(TimeGenerated)
            by ConvId;
earlyUrl
| join kind=fullouter earlyInj on ConvId
| extend ConvId = coalesce(ConvId, ConvId1)
| extend Contamination = coalesce(UrlHits, 0) + coalesce(InjHits, 0)
| where Contamination >= 1
| join kind=inner lateActs on ConvId
| join kind=leftouter convBounds on ConvId
| where SensitiveCalls >= 1
| extend AccountName = iff(isempty(AnyUser), "unknown-agent", AnyUser)
| project LastSeen, AccountName, UserId = AnyUser, ConvId, AnyChannel, AnyIp,
          Contamination, UntrustedHosts, SensitiveCalls, Connectors, Targets, FirstSensitive
| order by Contamination desc, SensitiveCalls desc

Explanation

This query is designed to detect a specific type of security threat in conversations with Microsoft Copilot Studio. Here's a simplified breakdown:

  1. Objective: The query identifies cases where an attacker might manipulate a conversation to trigger sensitive actions later. This is done by planting misleading data early in the conversation, which affects the system's behavior in later stages.

  2. Conversation Analysis:

    • The query examines conversations with at least five user interactions (turns).
    • It splits each conversation into four time segments (quartiles).
  3. Detection Criteria:

    • Early Contamination: In the first segment of the conversation, it looks for:
      • External URLs that are not from trusted Microsoft domains.
      • Specific phrases that might indicate an attempt to manipulate the system (injection markers).
    • Late Actions: In the last segment, it checks if any sensitive actions are triggered, such as calls to email, HTTP, SQL, Azure, SharePoint, etc.
  4. Data Sources: The query uses data from Application Insights, specifically looking at application events and dependencies.

  5. Alerting:

    • If both early contamination and late sensitive actions are detected, an alert is generated.
    • The alert includes details like the last time the issue was seen, the user involved, the conversation ID, and any untrusted hosts or sensitive actions detected.
  6. Severity and Frequency:

    • The severity of the alert is set to medium.
    • The query runs every hour and looks back over the past two hours.
  7. Additional Details:

    • The query includes lists of known injection markers and sensitive connectors.
    • It also maintains a list of safe Microsoft domains to filter out trusted URLs.
  8. Incident Management:

    • If an incident is detected, it is configured to create an alert and group related alerts by account.

Overall, this query is part of a security monitoring strategy to detect and alert on potential session context contamination in conversations with Microsoft Copilot Studio.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppEventsAppDependencies

Keywords

CopilotStudioApplicationInsightsAppEventsDependenciesMicrosoftAzureSQLSharePointDataversePowerShellOffice365OutlookExchangeWebhookAzureADLogicAppGraphKeyVaultBlobStorageDynamicsPowerPlatform

Operators

letdynamicagowhereextendtostringtolowerisnotemptysummarizecountminmaxtake_anyjoinkindonmax_ofdatetime_diffmin_oftointextracthas_anycountifcoalesceiffisemptyprojectorder by

Severity

Medium

Tactics

InitialAccessExecutionDefenseEvasion

MITRE Techniques

Frequency: PT1H

Period: PT2H

Actions

GitHub