Query Details

Foundry - Cross-server MCP / plugin instruction override

Foundry Mcp Cross Server Override

Query

let overrideMarkers = dynamic([
    "ignore the description","ignore your tool description",
    "instead use the","instead invoke","use the tool from",
    "override the","switch to the","use server","forget the previous tool",
    "this tool is deprecated, use","do not use this tool","call the function from",
    "the real tool is","disregard the schema","actually invoke","route to server"
]);
let markerRegex = strcat("(", strcat_array(overrideMarkers, "|"), ")");
let toolCalls =
    AppDependencies
    | where TimeGenerated > ago(1h)
    | extend
        Agent      = tostring(Properties["gen_ai.agent.name"]),
        ConvId     = tostring(Properties["gen_ai.conversation.id"]),
        Model      = tostring(Properties["gen_ai.request.model"]),
        ToolName   = tolower(tostring(Properties["gen_ai.tool.name"])),
        ToolServer = tolower(tostring(coalesce(
                        Properties["gen_ai.tool.server"],
                        Properties["mcp.server.name"],
                        Properties["microsoft.agent.tool.server"], ""))),
        ToolDesc   = tolower(tostring(coalesce(
                        Properties["gen_ai.tool.description"],
                        Properties["microsoft.agent.tool.description"],
                        Properties["mcp.tool.description"], ""))),
        ToolArgs   = tolower(tostring(Properties["gen_ai.tool.call.arguments"])),
        ToolResult = tolower(tostring(Properties["gen_ai.tool.call.result"]))
    | where isnotempty(ConvId) and isnotempty(ToolServer);
let convServers =
    toolCalls
    | summarize ServerCount = dcount(ToolServer),
                Servers     = make_set(ToolServer, 8)
        by ConvId
    | where ServerCount >= 2;
let suspect =
    toolCalls
    | extend Body = strcat(ToolDesc, " ", ToolArgs, " ", ToolResult)
    | where Body matches regex markerRegex
    | extend Marker = extract(markerRegex, 1, Body)
    | summarize OverrideHits = count(),
                Markers   = make_set(Marker, 8),
                Tools     = make_set(ToolName, 16),
                AnyAgent  = take_any(Agent),
                AnyModel  = take_any(Model),
                FirstSeen = min(TimeGenerated),
                LastSeen  = max(TimeGenerated)
        by ConvId;
suspect
| join kind=inner convServers on ConvId
| where OverrideHits >= 1
| extend AccountName = iff(isempty(AnyAgent), "unknown-agent", AnyAgent)
| project LastSeen, AccountName, Agent = AnyAgent, Model = AnyModel, ConvId,
          OverrideHits, ServerCount, Servers, Tools, Markers, FirstSeen
| order by OverrideHits desc

Explanation

This query is designed to detect a specific type of security threat involving malicious cross-server communication. Here's a simplified breakdown of what it does:

  1. Purpose: The query identifies instances where a malicious server tries to override the behavior of a tool from another server during a conversation. This is considered an abuse pattern because it exploits the trust between servers.

  2. Detection Method:

    • It looks for specific override phrases (like "ignore the description" or "use the tool from") in the tool's description, arguments, or result.
    • It requires that the conversation involves at least two different servers to filter out legitimate single-server interactions.
  3. Data Source: The query uses data from Application Insights, specifically the AppDependencies data type.

  4. Frequency and Scope:

    • The query runs every hour and checks data from the past two hours.
    • It triggers an alert if it finds any matches.
  5. Severity and Tactics: The threat is considered high severity and relates to tactics like Initial Access, Defense Evasion, Execution, and Lateral Movement.

  6. Output:

    • It lists conversations with detected override attempts, including details like the number of hits, involved servers, tools, and markers.
    • The results are sorted by the number of override hits.
  7. Incident Management: If an incident is detected, it creates an alert and can group related alerts into a single incident for easier management.

  8. Version and Tags: The rule is version 1.0.0 and is tagged for easy identification and categorization.

In essence, this query helps identify and alert on potential security breaches where a malicious server tries to manipulate tool behavior across different servers.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppDependencies

Keywords

ApplicationInsightsAppDependenciesAgentConvIdModelToolNameToolServerToolDescToolArgsToolResultTimeGeneratedConvServersServerCountServersOverrideHitsMarkersToolsAccountNameCloudApplicationLastSeenFirstSeenSentinelAsCodeCustomFoundryAIMCPAIRTv2

Operators

letdynamicstrcatstrcat_arraytolowertostringcoalesceisnotemptysummarizedcountmake_setbymatches regexextractcounttake_anyminmaxjoin kind=inneriffisemptyprojectorder by

Severity

High

Tactics

InitialAccessDefenseEvasionExecutionLateralMovement

MITRE Techniques

Frequency: PT1H

Period: PT2H

Actions

GitHub