EXPLORE
← Back to Explore
elasticmediumTTP

Unauthorized Scope for Public App OAuth2 Token Grant with Client Credentials

Identifies a failed OAuth 2.0 token grant attempt for a public client app using client credentials. This event is generated when a public client app attempts to exchange a client credentials grant for an OAuth 2.0 access token, but the request is denied due to the lack of required scopes. This could indicate compromised client credentials in which an adversary is attempting to obtain an access token for unauthorized scopes. This is a [New Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) rule where the `okta.actor.display_name` field value has not been seen in the last 14 days regarding this event.

MITRE ATT&CK

defense-evasion

Detection Query

data_stream.dataset: okta.system
    and event.action: "app.oauth2.as.token.grant"
    and okta.actor.type: "PublicClientApp"
    and okta.debug_context.debug_data.flattened.grantType: "client_credentials"
    and okta.outcome.result: "FAILURE"
    and not okta.client.user_agent.raw_user_agent: "Okta-Integrations"
    and not okta.actor.display_name: (Okta* or Datadog)
    and not okta.debug_context.debug_data.flattened.requestedScopes: ("okta.logs.read" or "okta.eventHooks.read" or "okta.inlineHooks.read")
    and okta.outcome.reason: "no_matching_scope"

Author

Elastic

Created

2024/09/11

Data Sources

Oktafilebeat-*logs-okta*

Tags

Domain: SaaSData Source: OktaUse Case: Threat DetectionUse Case: Identity and Access AuditTactic: Defense EvasionResources: Investigation Guide
Raw Content
[metadata]
creation_date = "2024/09/11"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies a failed OAuth 2.0 token grant attempt for a public client app using client credentials. This event is
generated when a public client app attempts to exchange a client credentials grant for an OAuth 2.0 access token, but
the request is denied due to the lack of required scopes. This could indicate compromised client credentials in which an
adversary is attempting to obtain an access token for unauthorized scopes. This is a [New
Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) rule where the
`okta.actor.display_name` field value has not been seen in the last 14 days regarding this event.
"""
from = "now-9m"
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Unauthorized Scope for Public App OAuth2 Token Grant with Client Credentials"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Unauthorized Scope for Public App OAuth2 Token Grant with Client Credentials

OAuth 2.0 is a protocol for authorization, allowing apps to access resources on behalf of users. Public client apps, lacking secure storage, use client credentials for token grants. Adversaries may exploit compromised credentials to request unauthorized scopes. The detection rule identifies failed token grants due to scope mismatches, signaling potential misuse of client credentials.

### Possible investigation steps

- Review the `okta.actor.display_name` field to identify the public client app involved in the failed token grant attempt and determine if it is a known or expected application.
- Examine the `okta.debug_context.debug_data.flattened.requestedScopes` field to understand which unauthorized scopes were requested and assess their potential impact if accessed.
- Investigate the `okta.actor.type` field to confirm that the actor is indeed a public client app, which lacks secure storage, and evaluate the risk of compromised credentials.
- Check the `okta.outcome.reason` field for "no_matching_scope" to verify that the failure was due to a scope mismatch, indicating an attempt to access unauthorized resources.
- Analyze the `okta.client.user_agent.raw_user_agent` field to ensure the request did not originate from known Okta integrations, which are excluded from the rule, to rule out false positives.
- Correlate the event with other security logs or alerts to identify any patterns or additional suspicious activities related to the same client credentials or IP address.

### False positive analysis

- Frequent legitimate access attempts by known public client apps may trigger false positives. To manage this, consider creating exceptions for specific `okta.actor.display_name` values that are known to frequently request scopes without malicious intent.
- Automated processes or integrations that use client credentials might occasionally request scopes not typically associated with their function. Review these processes and, if deemed non-threatening, exclude their `okta.client.user_agent.raw_user_agent` from triggering the rule.
- Development or testing environments often simulate various OAuth 2.0 token grant scenarios, which can result in false positives. Identify and exclude these environments by their `okta.actor.display_name` or other distinguishing attributes.
- Regularly review and update the list of non-threatening scopes in `okta.debug_context.debug_data.flattened.requestedScopes` to ensure that legitimate scope requests are not flagged as unauthorized.

### Response and remediation

- Immediately revoke the compromised client credentials to prevent further unauthorized access attempts.
- Conduct a thorough review of the affected public client app's access logs to identify any successful unauthorized access or data exfiltration attempts.
- Notify the application owner and relevant security teams about the incident to ensure coordinated response efforts.
- Implement additional monitoring on the affected app and associated user accounts to detect any further suspicious activities.
- Update and enforce stricter access controls and scope permissions for public client apps to minimize the risk of unauthorized scope requests.
- Consider implementing multi-factor authentication (MFA) for accessing sensitive resources to add an additional layer of security.
- Escalate the incident to the security operations center (SOC) for further investigation and to determine if broader organizational impacts exist."""
references = [
    "https://github.blog/news-insights/company-news/security-alert-stolen-oauth-user-tokens/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "6649e656-6f85-11ef-8876-f661ea17fbcc"
severity = "medium"
tags = [
    "Domain: SaaS",
    "Data Source: Okta",
    "Use Case: Threat Detection",
    "Use Case: Identity and Access Audit",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: okta.system
    and event.action: "app.oauth2.as.token.grant"
    and okta.actor.type: "PublicClientApp"
    and okta.debug_context.debug_data.flattened.grantType: "client_credentials"
    and okta.outcome.result: "FAILURE"
    and not okta.client.user_agent.raw_user_agent: "Okta-Integrations"
    and not okta.actor.display_name: (Okta* or Datadog)
    and not okta.debug_context.debug_data.flattened.requestedScopes: ("okta.logs.read" or "okta.eventHooks.read" or "okta.inlineHooks.read")
    and okta.outcome.reason: "no_matching_scope"
'''


[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

[[rule.threat.technique.subtechnique]]
id = "T1550.001"
name = "Application Access Token"
reference = "https://attack.mitre.org/techniques/T1550/001/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.new_terms]
field = "new_terms_fields"
value = ["okta.actor.display_name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-14d"