Query Details
id: e531f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a
name: "Zscaler ZPA - Access to Internal Application from Anomalous Geolocation"
version: 1.0.0
kind: Scheduled
description: |
Detects Zscaler Private Access (ZPA) connections to internal applications originating from countries the user has never accessed from in the previous 14 days. ZPA provides remote access to internal apps without a VPN; connections from unexpected geolocations indicate credential compromise, a threat actor using stolen credentials to access internal resources, or legitimate users travelling to unusual locations. MITRE ATT&CK: T1078 (Valid Accounts), T1133 (External Remote Services).
severity: High
requiredDataConnectors:
- connectorId: CommonSecurityEvents
dataTypes:
- CommonSecurityLog
queryFrequency: PT1H
queryPeriod: P14D
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- LateralMovement
relevantTechniques:
- T1078
- T1133
query: |
let recentWindow = 1h;
let baselineWindow = 14d;
let baseline = CommonSecurityLog
| where TimeGenerated between (ago(baselineWindow) .. ago(recentWindow))
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where DeviceAction !in ("block", "BLOCK", "Failed")
| where isnotempty(SourceUserName) and isnotempty(SourceIP)
| extend SrcCountry = tostring(geo_info_from_ip_address(SourceIP).country)
| summarize BaselineCountries = make_set(SrcCountry)
by SourceUserName;
let recent = CommonSecurityLog
| where TimeGenerated > ago(recentWindow)
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where DeviceAction !in ("block", "BLOCK", "Failed")
| where isnotempty(SourceUserName) and isnotempty(SourceIP)
| extend SrcCountry = tostring(geo_info_from_ip_address(SourceIP).country)
| summarize
RecentCountries = make_set(SrcCountry),
AccessedApps = make_set(DestinationHostName, 10),
ConnectionCount = count(),
SrcIPs = make_set(SourceIP, 5)
by SourceUserName;
recent
| join kind=leftouter baseline on SourceUserName
| extend BaselineCountries = coalesce(BaselineCountries, dynamic([]))
| extend NewCountries = set_difference(RecentCountries, BaselineCountries)
| where array_length(NewCountries) > 0
| project SourceUserName, NewCountries, AccessedApps, ConnectionCount, SrcIPs
| order by ConnectionCount desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: SourceUserName
customDetails:
ConnectionCount: ConnectionCount
NewCountries: NewCountries
AccessedApps: AccessedApps
alertDetailsOverride:
alertDisplayNameFormat: "ZPA Anomalous Geolocation - {{SourceUserName}} from new countries"
alertDescriptionFormat: "ZPA user {{SourceUserName}} connected from {{NewCountries}} — not seen in 14-day baseline. {{ConnectionCount}} connections to internal apps."
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT6H
matchingMethod: Selected
groupByEntities:
- Account
groupByAlertDetails: []
groupByCustomDetails: []
This query is designed to detect unusual access patterns to internal applications using Zscaler Private Access (ZPA). Here's a simplified breakdown of what it does:
Purpose: It identifies when a user accesses internal applications from a country they haven't connected from in the past 14 days. This could indicate a security issue, such as compromised credentials or a legitimate user traveling to an unusual location.
Data Source: It uses logs from Zscaler's CommonSecurityLog, focusing on successful connections (not blocked or failed attempts).
Time Frames:
Process:
Output: The query outputs details such as the username, new countries accessed, applications accessed, the number of connections, and source IPs. It orders the results by the number of connections.
Alerting: If any anomalies are detected, it creates an alert with details about the user and the new countries accessed. It also supports incident creation and grouping based on user accounts.
Severity and Techniques: The alert is marked with high severity and is associated with MITRE ATT&CK techniques related to valid accounts and external remote services.
In summary, this query helps identify potentially unauthorized access to internal applications by detecting connections from new and unusual geolocations.

David Alonso
Released: March 2, 2026
Tables
Keywords
Operators