Query Details

Copilot Studio - Suspicious or phishing URL in prompt or response

Copilot Studio Suspicious Url In Content

Query

let shorteners = dynamic(["bit.ly","tinyurl.com","t.co","goo.gl","ow.ly","is.gd","buff.ly","rb.gy","cutt.ly","rebrand.ly"]);
let baitPaths  = dynamic(["login","signin","verify","secure","account","update","reset","password","wallet","seed","mfa","authenticate","confirm"]);
let riskyTlds  = dynamic([".zip",".mov",".xyz",".top",".click",".country",".gq",".tk",".ml",".cf",".ga",".rest",".quest"]);
AppEvents
| where Name in ("BotMessageReceived", "BotMessageSend")
| extend
    ConvId    = tostring(Properties["conversationId"]),
    ChannelId = tostring(Properties["channelId"]),
    Direction = iff(Name == "BotMessageReceived", "UserPrompt", "AgentResponse"),
    Text      = tostring(Properties["text"])
| where isnotempty(Text)
| mv-expand Url = extract_all(@"(https?://[^\s\)\]\}""'<>]+)", Text) to typeof(string)
| extend
    Host = tolower(tostring(extract(@"https?://([^/:\s]+)", 1, Url))),
    Path = tolower(tostring(extract(@"https?://[^/]+(/[^\s]*)?", 1, Url)))
| extend Tld = tolower(tostring(extract(@"(\.[a-z]+)$", 1, Host)))
| extend
    RawIpHost  = Host matches regex @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",
    Punycode   = Host contains "xn--",
    Shortener  = Host in (shorteners),
    RiskyTld   = set_has_element(riskyTlds, Tld),
    BaitPath   = Path has_any (baitPaths),
    AtTrick    = Url matches regex @"https?://[^/\s]+@"
| extend RiskScore = toint(RawIpHost) + toint(Punycode) + toint(Shortener)
                   + toint(RiskyTld) + toint(BaitPath) + toint(AtTrick)
| where RiskScore > 0
| extend Reasons = trim(",", strcat(
    iff(RawIpHost, "RawIP,", ""), iff(Punycode, "Punycode,", ""),
    iff(Shortener, "Shortener,", ""), iff(RiskyTld, "RiskyTLD,", ""),
    iff(BaitPath, "CredentialBaitPath,", ""), iff(AtTrick, "UserinfoTrick,", "")))
| extend AccountName = iff(isempty(UserId), "unknown-agent", UserId)
| project
    TimeGenerated, Direction, RiskScore, Reasons, AccountName, ConvId, ChannelId,
    Url = substring(Url, 0, 512), Host, SessionId, ClientIP, AppVersion
| order by RiskScore desc, TimeGenerated desc

Explanation

This query is designed to detect suspicious or phishing URLs in conversations within Copilot Studio, a conversational AI platform. Here's a simplified breakdown of what it does:

  1. Purpose: The query raises an alert when a URL with potentially malicious characteristics is detected in a conversation. This could be a URL sent by a user or generated by the AI agent.

  2. Detection Criteria: It looks for URLs that match certain suspicious patterns, including:

    • URLs with raw IP addresses.
    • URLs using punycode, which can be used for homograph attacks.
    • Known URL shorteners like bit.ly or tinyurl.com.
    • URLs with paths that suggest credential phishing, such as "login", "verify", or "reset-password".
    • URLs with risky or look-alike top-level domains (TLDs) like .zip or .xyz.
    • URLs containing user information tricks, such as the "@" symbol in the URL.
  3. Data Source: It analyzes text from AppEvents, which requires enabling "Log sensitive properties" in Application Insights settings.

  4. Risk Scoring: Each URL is assigned a risk score based on the presence of these suspicious characteristics. If the score is greater than zero, the URL is flagged.

  5. Output: The query outputs details such as the time the URL was generated, the direction of the message (user or agent), the risk score, reasons for the score, account name, conversation ID, channel ID, and the URL itself.

  6. Alert Configuration: If a suspicious URL is detected, an incident is created. Alerts are grouped by account, and incidents can be reopened if similar activity is detected within a six-hour lookback period.

  7. Frequency: The query runs every hour and checks for any new suspicious URLs within the past hour.

  8. Severity and Tactics: The severity of the alert is marked as high, and it relates to tactics like Initial Access and Execution, aligning with techniques T1566 (Phishing) and T1204 (User Execution).

Overall, this query acts as a triage tool to identify potential phishing attempts in AI-driven conversations, helping security teams to take further action if needed.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

AppEvents

Keywords

CopilotStudioPhishingMaliciousUrlAppEventsAccountIPUserAgentSessionClientApplicationInsights

Operators

letdynamicinextendtostringiffisnotemptymv-expandextract_alltolowerextractmatches regexcontainsset_has_elementhas_anytointtrimstrcatisemptyprojectsubstringorder bydesc

Severity

High

Tactics

InitialAccessExecution

MITRE Techniques

Frequency: PT1H

Period: PT1H

Actions

GitHub