Detection rules › Panther
Google Workspace OAuth Application Authorized with Privileged Scopes
Detects when a user authorizes an OAuth application with privileged scopes in Google Workspace. Privileged scopes grant broad access to sensitive data and administrative functions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | T1078.004 Valid Accounts: Cloud Accounts |
| Persistence | T1078.004 Valid Accounts: Cloud Accounts, T1098 Account Manipulation |
Rule body yaml
AnalysisType: rule
RuleID: "Google.Workspace.OAuth.Privileged.Scopes"
DisplayName: "Google Workspace OAuth Application Authorized with Privileged Scopes"
Filename: gsuite_oauth_privileged_scopes.py
LogTypes:
- GSuite.ActivityEvent
Enabled: true
Severity: Info
DedupPeriodMinutes: 60
Status: Experimental
Reference: https://businessinsights.bitdefender.com/the-chain-reaction-new-methods-for-extending-local-breaches-in-google-workspace
Description: >
Detects when a user authorizes an OAuth application with privileged scopes in Google Workspace.
Privileged scopes grant broad access to sensitive data and administrative functions.
Runbook: |
1. Query GSuite.ActivityEvent logs for all OAuth token authorize events by actor:email in the 7 days before and after this alert to identify if this is part of a pattern of suspicious OAuth grants
2. Search for the parameters:client_id across all users in the organization to determine if other users also authorized the same application
3. Review audit logs for any actions taken using the OAuth token between the authorization timestamp and now, filtering by parameters:app_name and the authorized scopes
Tags:
- GSuite
- Initial Access
- Persistence
- Account Manipulation
Reports:
MITRE ATT&CK:
- TA0001:T1078.004
- TA0003:T1098
SummaryAttributes:
- actor:email
- p_any_ip_addresses
Tests:
- Name: Malicious App Privileged Scopes
ExpectedResult: true
Log:
actor:
email: user@example.com
profileId: "123456789012345678901"
id:
applicationName: token
customerId: C01234abc
time: "2024-01-15 10:30:00.000000000"
uniqueQualifier: "987654321098765432"
ipAddress: 192.0.2.1
kind: admin#reports#activity
name: authorize
parameters:
app_name: SuspiciousThirdPartyApp
client_id: "123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com"
client_type: WEB
scope:
- https://www.googleapis.com/auth/admin.directory.user
- https://www.googleapis.com/auth/ediscovery
- https://www.googleapis.com/auth/drive
- https://www.googleapis.com/auth/cloud_search.query
type: auth
- Name: Normal App Normal Scopes
ExpectedResult: false
Log:
actor:
email: user@example.com
profileId: "123456789012345678901"
id:
applicationName: token
customerId: C01234abc
time: "2024-01-15 10:30:00.000000000"
uniqueQualifier: "987654321098765432"
ipAddress: 192.0.2.1
kind: admin#reports#activity
name: authorize
parameters:
app_name: LegitimateCalendarApp
client_id: "123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com"
client_type: WEB
scope:
- https://www.googleapis.com/auth/calendar
- https://www.googleapis.com/auth/gmail.send
type: auth
- Name: Non-OAuth Event
ExpectedResult: false
Log:
actor:
email: user@example.com
profileId: "123456789012345678901"
id:
applicationName: admin
customerId: C01234abc
time: "2024-01-15 10:30:00.000000000"
uniqueQualifier: "987654321098765432"
ipAddress: 192.0.2.1
kind: admin#reports#activity
name: CREATE_USER
type: USER_SETTINGS
- Name: OAuth App with Single Privileged Scope
ExpectedResult: true
Log:
actor:
email: admin@example.com
profileId: "123456789012345678901"
id:
applicationName: token
customerId: C01234abc
time: "2024-01-15 10:30:00.000000000"
uniqueQualifier: "987654321098765432"
ipAddress: 192.0.2.1
kind: admin#reports#activity
name: authorize
parameters:
app_name: AdminToolApp
client_id: "123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com"
client_type: WEB
scope:
- https://www.googleapis.com/auth/admin.directory.user
- https://www.googleapis.com/auth/calendar
type: auth
Detection logic
Condition
not (id.applicationName ne "token" or name ne "authorize")
This rule also runs imperative logic the parser cannot express as a filter; the conditions above are the structured part it could extract.
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
id.applicationName | ne | token |
name | ne | authorize |
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
actor | actor.email |
event_type | name |
ip_address | ipAddress |
app_name | parameters.app_name |